1.初识sed编辑器
sed编辑器也被称为流编辑器,和vim等普通的文本编辑器恰好相反。在普通的文本编辑器中,你可以使用键盘命令来交互式的插入、删除或替换数据中的文本。流编辑器则会在编辑器处理之前基于预先提供的一组规则来编辑数据流,sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中,sed编辑器会执行如下操作:
(1) 一次从输入中读取一行数据
(2)根据所提供的编辑器命令匹配数据
(3)按照命令修改流中的数据
(4)将新的数据输出到标准输出STDOUT
在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据并重复这过程。在流编辑器处理完流中的所有数据行后,它就会停止。由于命令是按顺序逐行给出的,sed编辑器只需对数据流进行一遍处理就可以完成编辑操作。sed命令的格式:sed 可选项 script file sed命令可选项说明
选项 |
描述 |
-e script |
在处理输入时,将script中指定的命令添加到已有命令中 |
-f file |
在处理输入时,将file中指定的命令添加到已有命令中 |
-n |
不产生命令输出,使用print命令来完成输出 |
2.在命令行中定义编辑器命令
默认情况下,sed编辑器会将指定的命令应用到STDIN输入流上,这样可以直接将数据通过管道输入到sed编辑器中进行处理。如下例所示:
[njust@njust tutorials]$ echo "This is the first sed demo" | sed 's/demo/Big demo/' This is the first sed Big demo
通过上面的例子我们可以看出,在sed编辑器中使用了s命令,s命令会用斜线后指定的第二个字符串来替换第一个字符串。当然,你也可以在整个文件中进行上述字符串替换操作,如下所示:
[njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. [njust@njust tutorials]$ sed 's/cat/dog/' data1.txt The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
注意:sed编辑器并不会修改文本文件的数据,它只会将修改后的数据发送到STDOUT,如果查看原始文件,我们可以发现原始文件并未发生变化。
[njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
3.在命令行中使用多个编辑器命令
如果要在sed命令行上执行多个命令,只需加上-e可选项即可。如下所示:
[njust@njust tutorials]$ sed -e 's/brown/yellow/; s/cat/dog/' data1.txt The quick yellow fox jumps over the lazy dog. The quick yellow fox jumps over the lazy dog. The quick yellow fox jumps over the lazy dog. The quick yellow fox jumps over the lazy dog. [njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
两个命令都作用到文件中的每行数据上,命令之间必须用分号隔开,并且在命令末尾和分号之间不能有空格。如果不想使用分号,也可以用bash shell中的次提示符来分隔命令。只需要输入第一个单引号标识出sed程序脚本的起始,bash会继续提示你输入更多命令,直到输入了标识结束的单引号为止。
4.从文件中读取编辑器命令
如果有大量要处理的sed命令,那么将它们放进一个单独的文件中通常会更方便一些,可以在sed命令中用-f选项来指定文件。
[njust@njust tutorials]$ cat sed_script.sed s/brown/yellow/ s/fox/duck/ s/cat/dog/ [njust@njust tutorials]$ sed -f sed_script.sed data1.txt The quick yellow duck jumps over the lazy dog. The quick yellow duck jumps over the lazy dog. The quick yellow duck jumps over the lazy dog. The quick yellow duck jumps over the lazy dog. [njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
5.更多sed编辑器功能
5.1 更多替换选项a.替换标记
替换命令在替换多行中的文本时能够正常工作,但默认情况下它只替换每行中出现的第一处。要让替换命令能够替换一行中不同地方出现的文本,必须使用替换标记。替换标记会在替换命令字符串后面设置。s/pattern/replacement/flags,有四种可用的替换标记:
(1) 数字,表明新文本将替换第几处模式匹配的地方
(2) g,表明新文本将会替换所有匹配的文本
(3) p,表明原先行的内容要打印出来
(4) w file,将替换的结果写到文件中
[njust@njust tutorials]$ cat data2.txt This is a test of the test script. [njust@njust tutorials]$ sed 's/test/demo/2' data2.txt This is a test of the demo script.
如上例所示,在第一类替换中,可以指定sed编辑器用新文本替换第几处模式匹配的地方。将替换标记指定为2的结果是:sed编辑器只会替换每行中第二次出现的匹配字符串。g替换标记能实现全替换功能,如下所示:
[njust@njust tutorials]$ sed 's/test/demo/g' data2.txt This is a demo of the demo script. [njust@njust tutorials]$ cat data2.txt This is a test of the test script.
p替换标记会打印与替换命令中指定的模式匹配的行,通常会和-n选项一起使用,如下所示:
[njust@njust tutorials]$ sed -n 's/test/demo/p' data3.txt This is a demo line. [njust@njust tutorials]$ cat data3.txt This is a test line. This is a different line.
w替换标记会产生同样的输出,不过会将输出保存到指定文件中。sed编辑器的正常输出是STDOUT中,而只有那些包含匹配模式的行才会保存在指定的输出文件中,如下所示:
[njust@njust tutorials]$ sed 's/test/demo/w test_sed.txt' data3.txt This is a demo line. This is a different line. [njust@njust tutorials]$ cat test_sed.txt This is a demo line. [njust@njust tutorials]$ cat data3.txt This is a test line. This is a different line.
b.替换字符
有时候你会在文本字符串中遇到一些不太方便在替换模式中使用的字符。例如正斜线/,它常见于linux系统文件路径中。你可能会想到,使用转义字符就可以啦,可是这通常会引起错误。要解决这个问题,sed编辑器允许选择其他字符作为替换命令中的字符串分隔符。例如,想用/bin/csh来替换/bin/bash,可以使用!作为字符串分隔符。如下所示:
[njust@njust tutorials]$ sed 's!/bin/bash!/bin/csh!' /etc/passwd root:x:0:0:root:/root:/bin/csh
5.2 使用地址
默认情况下,在sed编辑器中使用的命令会作用于文本数据中的所有行,如果只想命令作用于特定的行或某些行,必须使用行寻址。在sed编辑器中有两种形式的行寻址方式:
(1) 以数字形式表示行区间
(2) 用文本模式来过滤出行
a.数字方式的行寻址
当使用数字方式的行寻址时,可以用行在文本流中的位号来引用。sed编辑器会将文件流中的第一行编号为1,依次类推分配行号。也可以指定一定区间范围内的行号,如下例所示:
[njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. [njust@njust tutorials]$ sed '2s/cat/dog/' data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. [njust@njust tutorials]$ sed '2,4s/fox/duck/' data1.txt The quick brown fox jumps over the lazy cat. The quick brown duck jumps over the lazy cat. The quick brown duck jumps over the lazy cat. The quick brown duck jumps over the lazy cat.
如果想将命令作用到文本中从某行开始的所有行,可以用特殊地址$,如下所示:
[njust@njust tutorials]$ sed '2,$s/fox/duck/' data1.txt The quick brown fox jumps over the lazy cat. The quick brown duck jumps over the lazy cat. The quick brown duck jumps over the lazy cat. The quick brown duck jumps over the lazy cat. [njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
b.使用文本模式过滤
sed编辑器允许指定文本模式来过滤命令要作用的行,必须用正斜线/将要指定的文本模式封起来。sed编辑器会将该命令作用到包含指定文本模式的行上。例如只想修改njust用户的默认shell,可以使用sed命令。
[root@njust tutorials]# grep njust /etc/passwd njust:x:1000:1000:njust:/home/njust:/bin/bash [root@njust tutorials]# sed '/njust/s/bash/csh/' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin njust:x:1000:1000:njust:/home/njust:/bin/csh shenchao:x:1001:1001::/home/shenchao:/bin/bash
c.命令组合
如果需要在单行上执行多条命令,可以用花括号将多条命令组合在一起。sed编辑器会处理地址行处流出的每条命令。如下例所示:
[njust@njust tutorials]$ sed '2{ > s/fox/duck/ > s/cat/dog/ > }' data1.txt The quick brown fox jumps over the lazy cat. The quick brown duck jumps over the lazy dog. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. [njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
5.3 删除行
删除命令d它会删除匹配指定寻址模式的所有行,使用该命令时要特别小心,如果忘记加寻址模式,流中的所有文本都会被删除。如下例所示:
[njust@njust tutorials]$ sed 'd' data1.txt [njust@njust tutorials]$ cat data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
当和指定地址一起使用时,可以从数据流中删除特定的文本行,通过行号指定。如下所示:
[njust@njust tutorials]$ sed '3d' data4.txt This is line number 1 This is line number 2 This is line number 4 [njust@njust tutorials]$ sed '2,3d' data4.txt This is line number 1 This is line number 4 [njust@njust tutorials]$ sed '2,$d' data4.txt This is line number 1 [njust@njust tutorials]$ cat data4.txt This is line number 1 This is line number 2 This is line number 3 This is line number 4
sed编辑器的模式匹配特性也适用于删除命令,它会删除包含匹配指定模式的行,如下所示:
[njust@njust tutorials]$ sed '/number 2/d' data4.txt This is line number 1 This is line number 3 This is line number 4 [njust@njust tutorials]$ cat data4.txt This is line number 1 This is line number 2 This is line number 3 This is line number 4
也可以使用两个文本模式来删除某个区间(闭区间)内的行,指定的第一个模式会打开行删除功能,第二个模式会关闭行删除功能。sed编辑器会删除两个指定行之间的所有行。只要sed编辑器在数据流中匹配到了开始模式,删除功能就会打开,这就可能会导致意外的结果。如下例所示:
[njust@njust tutorials]$ sed '/1/,/3/d' data4.txt This is line number 4 [njust@njust tutorials]$ cat data4.txt This is line number 1 This is line number 2 This is line number 3 This is line number 4 This is line number 1 again This is text you want to keep
5.4 插入和附加文本
插入命令i会在指定行前增加一个新行,附加命令a会在指定行后增加一个新行。注意:当使用插入命令时,文本会出现在数据流文本的前面。当使用附加命令时,文本会出现在数据流文本的后面。如下例所示:
[njust@njust tutorials]$ echo "Test Line 2" | sed 'i\Test Line 1' Test Line 1 Test Line 2 [njust@njust tutorials]$ echo "Test Line 2" | sed 'a\Test Line 1' Test Line 2 Test Line 1
要插入或附加多行文本,就必须对要插入或附加的新文本中的每行使用反斜线,直到最后一行。如下例所示:
[njust@njust tutorials]$ sed '1i\This is one line of new text\ This is another line of new text.' data4.txt This is one line of new text This is another line of new text. This is line number 1 This is line number 2 This is line number 3 This is line number 4 This is line number 1 again This is text you want to keep
5.5 修改行
修改命令c允许修改数据流中整行文本的内容,必须在sed命令中单独指定新行,如下例所示:
[njust@njust tutorials]$ sed '3c\This is a changed line of text' data4.txt This is line number 1 This is line number 2 This is a changed line of text This is line number 4 This is line number 1 again This is text you want to keep [njust@njust tutorials]$ cat data4.txt This is line number 1 This is line number 2 This is line number 3 This is line number 4 This is line number 1 again This is text you want to keep
5.6 转换命令
转换命令y是唯一可以处理单个字符的sed编辑器命令,如果输入字符和输出字符的长度不同,则sed编辑器会产生一条错误消息。如下例所示:
[njust@njust tutorials]$ sed 'y/123/789/' data4.txt This is line number 7 This is line number 8 This is line number 9 This is line number 4 This is line number 7 again This is text you want to keep [njust@njust tutorials]$ cat data4.txt This is line number 1 This is line number 2 This is line number 3 This is line number 4 This is line number 1 again This is text you want to keep