一、sed脚本定义
Vim 采用的是交互式文本编辑模式,可以用键盘命令来交互性地插入、删除或替换数据中的文本。 sed 命令不同,它采用的是流编辑模式,最明显的特点是,在 sed 处理数据之前,需要预先提供一组规则,sed 会按照此规则来编辑数据。
1、sed的特点
(1)sed 会根据脚本命令来处理文本文件中的数据,这些命令要么从命令行中输入,要么存储在一个文本文件中 。
(2)每次仅读取一行内容;
(3)根据提供的规则命令匹配并修改数据。注意,sed 默认不会直接修改源文件数据,而是会将数据复制到缓冲区中,修改也仅限于缓冲区中的数据;
(4)将执行结果输出。
2、sed基本格式
[root@localhost ~]# sed [选项] [脚本命令] 文件名
注意:本章从“二”到“十”的,带单引号的都是脚本命令。
选项 | 含义 |
---|---|
-e 脚本命令 | 该选项会将其后跟的脚本命令添加到已有的命令中。 |
-f 脚本命令文件 | 该选项会将其后文件中的脚本命令添加到已有的命令中。 |
-n | sed 会自动内容,这个屏蔽输出,需使用 print 命令来完成输出。 |
-i | 此选项会直接修改源文件。 |
二、sed s 替换脚本命令
1、s替换基本格式
[address]s/pattern/replacement/flags
注释: (1)address 表示指定要操作的行。
(2)pattern 指的是需要替换的内容。
(3)replacement 指的是要替换的新内容。
(4)flags如下:
s替换的flags 标记 | 功能 |
---|---|
n | 1~512 之间的数字,如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个“2”标记; |
g | 对所有匹配到的内容进行替换,当无 g则只在第一次匹配成功时做替换操作。 |
p | 打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。 |
w file | 将缓冲区中的内容写到指定的 file 文件中; |
& | 用正则表达式匹配的内容进行替换; |
\n | 匹配第 n 个子串,该子串之前在 pattern 中用 \(\) 指定。 |
\ | 转义(转义替换部分包含:&、\ 等)。 |
2、 具体应用
"1、sed 编辑器只替换每行中第 2 次出现的匹配模式"
[root@localhost ~]sed ‘s/test/trial/2’ data4.txt
#This is a test of the trial script.
#This is the second test of the trial script.
"2、用新文件替换所有匹配的字符串,可以使用 g 标记"
[root@localhost ~]sed ‘s/test/trial/g’ data4.txt
#This is a trial of the trial script.
#This is the second trial of the trial script.
"3、-n 选项会禁止 sed 输出,但 p 标记会输出修改过的行,
将二者匹配使用的效果就是只输出被替换命令修改过的行"
[root@localhost ~]cat data5.txt
#This is a test line.
#This is a different line.
[root@localhost ~]sed -n ‘s/test/trial/p’ data5.txt
#This is a trial line.
"4、w 标记会将匹配后的结果保存到指定文件中"
[root@localhost ~]sed ‘s/test/trial/w test.txt’ data5.txt
#This is a trial line.
#This is a different line.
[root@localhost ~]cat test.txt
#This is a trial line.
"5、使用 s 脚本命令时,替换类似文件路径麻烦,需要转义"
[root@localhost ~]sed ‘s/\/bin\/bash/\/bin\/csh/’ /etc/passwd
三、sed d 删除脚本命令
如果需要删除文本中的特定行,可以用 d 脚本命令,它会删除指定行中的所有内容。如果忘记指定具体行的话,文件中的所有内容都会被删除。
1、基本格式
[address]d
2、基本应用
"1、不指定行,将删除所有行"
[root@localhost ~]cat 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
[root@localhost ~]sed ‘d’ data1.txt
#什么也不输出,证明成了空文件
"2、删除 data6.txt 文件内容中的第 3 行"
[root@localhost ~]cat data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 3.
#This is line number 4.
[root@localhost ~]sed ‘3d’ data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 4.
"3、删除 data6.txt 文件内容中的第 2、3行"
[root@localhost ~]sed ‘2,3d’ data6.txt
#This is line number 1.
#This is line number 4.
"4、通过特殊的文件结尾字符,比如删除 data6.txt 文件内容中第 3 行开始的所有的内容"
[root@localhost ~]sed ‘3,$d’ data6.txt
#This is line number 1.
#This is line number 2.
注意:默认情况下 sed 并不会修改原始文件,这里被删除的行只是从 sed 的输出中消失了,原始文件没做任何改变。
四、sed的“a”(附加)和“i”(插入)指令
a 命令表示在指定行的后面附加一行,i 命令表示在指定行的前面插入一行
1、基本格式
[address]a(或 i)\新文本内容
2、基本用法
"1、将一个新行插入到数据流第三行前"
[root@localhost ~]sed ‘3i\
> This is an inserted line.’ data6.txt
#This is line number 1.
#This is line number 2.
#This is an inserted line.
#This is line number 3.
#This is line number 4.
"2、将一个新行附加到数据流中第三行后"
[root@localhost ~]sed ‘3a\
> This is an appended line.’ data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 3.
#This is an appended line.
#This is line number 4.
"3、将一个多行数据添加到数据流中,只需对要插入或附加的文本中的每一行末尾
(除最后一行)添加反斜线即可"
[root@localhost ~]sed ‘1i\
> This is one line of new text.\
> This is another line of new text.’ data6.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.
五、sed c 替换脚本命令
前边s是替换某个词,这里c 是替换一整行
1、基本格式
[address]c\用于替换的新文本
2、基本应用
"1、sed 编辑器会修改第三行中的文本"
[root@localhost ~]sed ‘3c\
> This is a changed line of text.’ data6.txt
#This is line number 1.
#This is line number 2.
#This is a changed line of text.
#This is line number 4.
"2、相同功能"
[root@localhost ~]sed ‘/number 3/c\
> This is a changed line of text.’ data6.txt
#This is line number 1.
#This is line number 2.
#This is a changed line of text.
#This is line number 4.
六、sed y 转换脚本命令
1、基本格式
[address]y/inchars/outchars/
转换命令会对 inchars 和 outchars 值进行一对一的映射,即 inchars 中的第一个字符会被转换为 outchars 中的第一个字符,第二个字符会被转换成 outchars 中的第二个字符...这个映射过程会一直持续到处理完指定字符。如果 inchars 和 outchars 的长度不同,则 sed 会产生一条错误消息。
2、基本应用
[root@localhost ~]sed 'y/123/789/' data8.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 yet another line.
#This is the last line in the file.
inchars 模式中指定字符的每个实例都会被替换成 outchars 模式中相同位置的那个字符。转换命令是一个全局命令,也就是说,它会文本行中找到的所有指定字符自动进行转换,而不会考虑它们出现的位置。
[root@localhost ~]echo "This 1 is a test of 1 try." | sed 'y/123/456/'
#This 4 is a test of 4 try.
七、sed p 打印脚本命令
p 命令表示搜索符号条件的行,并输出该行的内容
1、基本格式
[address]p
2、基本应用
"1、用 -n 选项和 p 命令配合使用,我们可以禁止输出其他行,只打印包含匹配文本模式的行"
[root@localhost ~]cat data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 3.
#This is line number 4.
[root@localhost ~]sed -n ‘/number 3/p’ data6.txt
#This is line number 3.
"2、在修改行之前显示该行"
[root@localhost ~]sed -n ‘/3/{
> p
> s/line/test/p
> }’ data6.txt
#This is line number 3.
#This is test number 3.
八、sed w 脚本命令
w 命令用来将文本中指定行的内容写入文件中
1、基本格式
[address]w filename
filename 表示文件名,可以使用相对路径或绝对路径,但不管是哪种,运行 sed 命令的用户都必须有文件的写权限。
2、基本使用
"1、将数据流中的前两行打印到一个文本文件中"
[root@localhost ~]sed '1,2w test.txt' data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 3.
#This is line number 4.
[root@localhost ~]cat test.txt
#This is line number 1.
#This is line number 2.
"2、如果不想让行直接输出,可以用 -n 选项"
[root@localhost ~]cat data11.txt
#Blum, R Browncoat
#McGuiness, A Alliance
#Bresnahan, C Browncoat
#Harken, C Alliance
[root@localhost ~]sed -n '/Browncoat/w Browncoats.txt' data11.txt
[root@localhost ~]cat Browncoats.txt
#Blum, R Browncoat
#Bresnahan, C Browncoat
九、sed r 脚本命令
r 命令用于将一个独立文件的数据插入到当前数据流的指定位置。r是插入到行后,i是行前
1、基本格式
[address]r filename
2、基本用法
'1、sed 命令会将 filename 文件中的内容插入到 address 指定行的后面'
[root@localhost ~]cat data12.txt
#This is an added line.
#This is the second added line.
[root@localhost ~]sed '3r data12.txt' data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 3.
#This is an added line.
#This is the second added line.
#This is line number 4.
"2、如果你想将指定文件中的数据插入到数据流的末尾,可以使用 $ 地址符"
[root@localhost ~]sed '$r data12.txt' data6.txt
#This is line number 1.
#This is line number 2.
#This is line number 3.
#This is line number 4.
#This is an added line.
#This is the second added line.
十、sed q 退出脚本命令
q 命令的作用是使 sed 命令在第一次匹配任务结束后,退出 sed 程序,不再进行对后续数据的处理。
1、基本使用
"1、使用 q 命令之后,sed 命令会在匹配到 number 1 时,
将其替换成 number 0,然后直接退出"
[root@localhost ~]sed '2q' test.txt
#This is line number 1.
#This is line number 2.
[root@localhost ~]sed '/number 1/{ s/number 1/number 0/;q; }' test.txt
#This is line number 0.
十一、sed 脚本命令的寻址方式
我们一直忽略了对 address 部分的介绍。对各个脚本命令来说,address 用来表明该脚本命令作用到文本中的具体行。
注意:
默认情况下,sed 命令会作用于文本数据的所有行(之前的都是默认情况下,作用在所有行)。如果只想将命令作用于特定行或某些行,则必须写明 address 部分,表示的方法有以下 2 种:
(1)以数字形式指定行区间;
(2)用文本模式指定具体行区间。
确定address的两种格式:
(1)[address]脚本命令
(2)address {
多个脚本命令
}
1、以数字形式指定行区间
当使用数字方式的行寻址时,可以用行在文本流中的行位置来引用。sed 会将文本流中的第一行编号为 1,然后继续按顺序为接下来的行分配行号。在脚本命令中,指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行。这里举一个 sed 命令作用到指定行号的例子:
"1、指定的地址可以是单个行号"
[root@localhost ~]sed '2s/dog/cat/' data1.txt
#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 dog
#The quick brown fox jumps over the lazy dog
"2、使用了行地址区间"
[root@localhost ~]sed '2,3s/dog/cat/' data1.txt
#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
#The quick brown fox jumps over the lazy dog
"3、如果想将命令作用到文本中从某行开始的所有行,可以用特殊地址——美元符($)"
[root@localhost ~]sed '2,$s/dog/cat/' data1.txt
#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
#The quick brown fox jumps over the lazy cat
2、用文本模式(正则表达式)指定行区间
1、基本格式
/pattern/command
注意,必须用正斜线将要指定的 pattern 封起来,sed 会将该命令作用到包含指定文本模式的行上。
2、基本应用
[root@localhost ~]# grep demo /etc/passwd
demo:x:502:502::/home/Samantha:/bin/bash
[root@localhost ~]# sed '/demo/s/bash/csh/' /etc/passwd
"/demo/正则表达式,s是替换文本命令"
root:x:0:0:root:/root:/bin/bash
...
demo:x:502:502::/home/demo:/bin/csh
...
3、文本模式用正则表达式
正则表达式允许创建高级文本模式匹配表达式来匹配各种数据。这些表达式结合了一系列通配符、特殊字符以及固定文本字符来生成能够匹配几乎任何形式文本的简练模式。