sed 命令是一个非交互式的行文本编辑器,它能对文件内容进行编辑,默认每次处理文本文件中所匹配到一行内容到模式空间,然后用后面的命令进行操作,操作完成之后,会把模式空间里面的内容输出到屏幕上,然后把模式空间中的内容删除,同时把下一行所匹配到的内容读入模式空间内,依次循环,直到读取完整个文件。
Sed主要用来自动编辑一个或多个文件,可以将数据行进行替换、删除、新增、选取等特定工作,简化对文件的反复操作,编写转换程序等。

语法

1
2
sed [options] 'address command' file
sed [options] -f [scripefile] file

对以上的语法进行说明:

  • options 为选项,其中 sed 支持的选项会在下面的选项小结说明
  • address : 相当于匹配的条件,会在地址中进行说明
  • command 为命令,相当于一个参数,放在地址后面,具体见下面的命令小节说明
  • file :为文本文件

需要说明的是,使用时 address 和 command 会挨在一起,中间没有空格,上面语法中间加空格是为了说明这是两个部分

选项

选项 意义
-e 可以指定多个命令’address command’内用;隔开
-f 该选项会将其后文件中的脚本命令添加到已有的命令中。
-n 默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容,而该选项会屏蔽启动输出,需使用 print 命令来完成输出。
-i 此选项会直接修改源文件,要慎用。
-r 支持扩展正则表达式;

地址

这里的地址就是语法格式中的 address 部分,是在单引号里的前一部分 。

1
2
3
4
5
6
7
8
9
10
cat testfile -n
1 Having nothing, nothing can he lose
2 到了黄金不起支配作用的时候,黄金时代才到来
3 Wombat's Laws of Computer Selection:
4 (1) If it doesn't run Unix, forget it.
5 (2) Any computer design over 10 years old is obsolete.
6 (3) Anything made by IBM is junk. (See number 2)
7 (4) The minimum acceptable CPU power for a single user is a
8 VAX/780 with a floating point accelerator.
9 (5) Any computer with a mouse is worthless.

替换标记说明

模式 样例 输出
linenumber 指定特定行号 sed -n ‘2p’ testfile 到了黄金不起支配作用的时候,黄金时代才到来
startline,endline 指定起始行号和结束行号 sed -n ‘1,3p’ testfile Having nothing, nothing can he lose
到了黄金不起支配作用的时候,黄金时代才到来
linenumber,+n n 为数字,表示从指定行号向后 n 行 sed -n ‘1,+2p’ testfile Having nothing, nothing can he lose
到了黄金不起支配作用的时候,黄金时代才到来
/pattern / 已正则表达式表示的匹配模式 sed -n ‘/Having/p’ testfile Having nothing, nothing can he lose
/pattern1, /pattern2 / 从模式匹配 1 到模式匹配 2 sed -n ‘/Having/,/Wombat/p’ testfile Having nothing, nothing can he lose
到了黄金不起支配作用的时候,黄金时代才到来
Wombat’s Laws of Computer Selection:
/pattern/,x 在给定行号上查询包含模式的行 sed -n ‘/Having/,2p’ testfile Having nothing, nothing can he lose
到了黄金不起支配作用的时候,黄金时代才到来
x,/pattern / 通过行号和模式查询匹配的行 sed -n ‘2,/Wombat/p’ testfile 到了黄金不起支配作用的时候,黄金时代才到来
Wombat’s Laws of Computer Selection:
! 前面的查询范围取反 sed -n ‘/Having/,+3!p’ testfile (2) Any computer design over 10 years old is obsolete.
(3) Anything made by IBM is junk. (See number 2)
(4) The minimum acceptable CPU power for a single user is a
VAX/780 with a floating point accelerator.
(5) Any computer with a mouse is worthless.

命令

命令 意义
a 追加,向匹配行后面插入内容
i 插入,向匹配行前插入内容
c 更改,更改匹配行的内容
d 删除,删除匹配行的内容
s 使用替换模式替换相应模式,s语法为 [address]s/pattern/replacement/flags ,把 patten 匹配到的内容换成 replacement,并且还有标记配合使用,见下替换标记
p 打印,打印出匹配的内容,通过与 - n 选项配合使用
q 退出命令
= 标号,用来将匹配的行前标号
n 读取下一行,遇到 n 会自动自动跳入下一行
r 将内容读入文件
{} 命令间的传递,类似于管道符 |
w 将匹配内容写入文件
W 将匹配到行的第一行,保存到 file 中。

替换标记

flags 标记 功能
n 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个标记;
g 对数据中所有匹配到的内容进行替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A;
p 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。
w file 将缓冲区中的内容写到指定的 file 文件中;
& 用正则表达式匹配的内容进行替换;
\n 匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。
\ 转义(转义替换部分包含:&、\ 等)。

特殊字符

许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符 “转义”,即,将反斜杠字符 \ 放在它们前面。下表列出了正则表达式中的特殊字符:

特别字符描述
$匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用
*匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
.匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
[标记一个中括号表达式的开始。要匹配 [,请使用 \[。
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
^匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。
{标记限定符表达式的开始。要匹配 {,请使用 \{。
|指明两项之间的一个选择。要匹配 |,请使用 \|。

实例

查看指定行数内容

1
sed -n '1,3p' testfile

删除指定行

1
2
3
sed -i '1,2d' testfile
sed -i '1,+3d' testfile
# 不加-i参数,不修改原文件,只会输出修改后文件内容

删除匹配Having的行

1
sed -i '/Having/d' testfile

查找打印–开头的行

1
sed -n '/^--/p' ysl.sql

打印行号和内容

1
2
3
sed -n -e '2,3=';'2,3p' testfile
sed -n -e '2,3=;2,3p' testfile
sed -n '/boot/=' aa.txt 

打印匹配以 d 开头到以 l 开头的行 (多次匹配)

1
sed -n '/nothing/,/it/p' testfile

过滤掉注释的行,备注:注释的行是以 #开头

1
sed -n '/^#/!p' testfile

过滤掉所有的空行

1
sed -n '/^$/!p' testfile

过滤掉所有注释行和空行,此命令用到 {}

1
sed -n '/^#/!{/^$/!p}' testfile

删除掉所有注释行和空行

1
sed -i -e '/^#/d' -e '/^$/d' testfile

替换第一次出现nothing,这里第一次都是指一行的第一次

1
sed -n 's/nothing/notis/1p' testfile

整个文件只替换一次,将nothing替换为something

1
sed -i '0,/nothing/s//something/' testfile

替换所有

1
sed -n 's/nothing/notis/gp' testfile

包含is的行,每行行首添加containis

1
sed -n '/is/s/^/containis/p' testfile

在匹配 See 字符的行,在 See 字符后添加 hello,在 See 字符前添加 hello

1
sed -n  '/See/s/See/& Hello/p' java.conf   sed -n  '/See/s/See/Hello &/p' java.conf   & 表示前面匹配到的内容

在匹配 ddd 字符的行的前面一行添加 hello

1
sed '/aaa/i hello' info 

在匹配 ddd 字符的行的后面一行添加 hello

1
sed '/aaa/a hello' info

替换第三行内容

1
sed -i '3c\this is line' aa.txt

将文件 info 中的前两行输出到文本文件 aa.txt

1
sed '1,2w aa.txt' info

将 info 中匹配 boot 的行写入到 aa.txt 中

1
sed '/boot/w aa.txt' info

将文件 info 中匹配到 tmp 的行,其中包含 root 的字符修改为 test

1
sed -i '/tmp/s/root/test/g' aa.txt 

参考:
sed命令全面解析_wht1995316的博客-CSDN博客
Linux之sed命令详解 | 《Linux就该这么学》 (linuxprobe.com)
Linux sed命令完全攻略(超级详细) (biancheng.net)