Linux sed 命令详解系列教程之入门篇(2)

'-n'
默认情况下,sed将在每轮script循环结束时自动输出模式空间中的内容。使用该选项后可以使得这次自动输出动作输出空内容,而不是当前模式空间中的内容。注意,"-n"是输出空内容而不是禁用输出动作,虽然两者的结果都是不输出任何内容,但在有些依赖于输出动作和输出流的地方,它们的区别是很大的,前者有输出流,只是输出空流,后者则没有输出流。

'-e SCRIPT'
前文说了,SCRIPT中包含的是命令的集合,"-e"选项就是向SCRIPT中添加命令的。可以省略"-e"选项,但如果命令行容易产生歧义,则使用"-e"选项可明确说明这部分是SCRIPT中的命令。另外,如果一个"-e"选项不方便描述所需命令集合时,可以指定多个"-e"选项。

'-f SCRIPT-FILE'
指定包含命令集合的SCRIPT文件,让sed根据SCRIPT文件中的命令集处理输入流。

'-i[SUFFIX]'
该选项指定要将sed的输出结果保存(覆盖的方式)到当前编辑的文件中。GNU sed是通过创建一个临时文件并将输入写入到该临时文件,然后重命名为源文件来实现的。

当当前输入流处理结束后,临时文件被重命名为源文件的名称。如果还提供了SUFFIX,则在重命名临时文件之前,先使用该SUFFIX修改源文件名,从而生成一个源文件的备份文件。

临时文件总是会被重命名为源文件名称,也就是说输入流处理结束后,仍使用源文件名的文件是sed修改后的文件。文件名中包含了SUFFIX的文件则是最原始文件的备份。例如源文件为a.txt,sed -i'.log' SCRIPT a.txt将生成两个文件:a.txt和a.txt.log,前者是sed修改后的文件,a.txt.log是源a.txt的备份文件。

重命名的规则如下:如果扩展名不包含符号"*",将SUFFIX添加到原文件名的后面当作文件后缀;如果SUFFIX中包含了一个或多个字符"*",则每个"*"都替换为原文件名。这使得你可以为备份文件添加一个前缀,而不是后缀。如果没有提供SUFFIX,源文件被覆盖,且不会生成备份文件。

该选项隐含了"-s"选项。

'-r'
使用扩展正则表达式,而不是使用默认的基础正则表达式。sed所支持的扩展正则表达式和egrep一样。使用扩展正则表达式显得更简洁,因为有些元字符不用再使用反斜线"\"。正则表达式见grep命令中文手册

'-s'
默认情况下,如果为sed指定了多个输入文件,如sed OPTIONS SCRIPT file1 file2 file3,则多个文件会被sed当作一个长的输入流,也就是说所有文件被当成一个大文件。指定该选项后,sed将认为命令行中给定的每个文件都是独立的输入流。

既然是独立的输入流,范围定址(如/abc/,/def/)就无法跨越多个文件进行匹配,行号也会在处理每个文件时重置,"$"代表的也将是每个文件的最后一行。这也意味着,如果不使用该选项,则这几个行为都是可以完成的。

示例:以sed命令"p"和"="为例,其中"p"命令用于强制输出当前模式空间中的内容,"="命令用于输出sed行号计数器当前的值,即刚被读入到模式空间中的行是输入流中的第几行。

(1).只输出a.txt中的第5行。

sed -n 5p a.txt

这里使用了"-n"选项,使得读取到模式空间的每一行都无法被输出,只有明确使用了"p"选项才能被"p"动作输出。由于只有读入的第5行内容能匹配"5",才能被"p"输出。

其实上面的命令和sed -n -e '5p' a.txt是完全一样的,因为"5p"在sed解析命令行时不会产生歧义,所以可以省略"-e"选项。

(2).输出a.txt,并输出每行的行号。

sed '=' a.txt

由于要输出a.txt的内容,所以不使用"-n"选项,同时"="命令会输出每行行号。

(3).分别输出a.txt和b.txt的第5行,并分别保存到".bak"后缀的文件中。

sed -i'*.bak' -n '5p' a.txt b.txt

此处必须使用"-s"选项,否则将只会输出"a.txt+b.txt"结合后的第5行。但"-i"隐含了"-s"选项。这会生成4个文件:a.txt、b.txt和a.txt.bak、b.txt.bak。前两个是第5行内容,后两个是源文件的备份文件。

(4).使用扩展正则表达式,输出a.txt和b.txt中能包含3个以上字母"a"的行。

sed -r -n '/aaa+/p' a.txt b.txt

3.定址表达式

当sed将输入流中的行读取到模式空间后,就需要对模式空间中的内容进行匹配,如果能匹配就能执行对应的命令,如果不能匹配就直接输出、清空模式空间并进入下一个sed循环读取下一行。

匹配的过程称为定址。定址表达式有多种,但总的来说,其格式为[ADDR1][,ADDR2]。这可以分为3种方式:

ADDR1和ADDR2都省略时,表示所有行都能被匹配上。

省略ADDR2时,表示只有被ADDR1表达式匹配上的行才符合条件。

不省略ADDR2时,是范围地址。表示从ADDR1匹配成功的行开始,到ADDR2匹配成功的行结束。

无论是ADDR1还是ADDR2,都可以使用两种方式进行匹配:行号和正则表达式。如下:

'N'
指定一个行号,sed将只匹配该行。(需要注意,除非使用了"-s"或"-i"选项,sed将对所有输入文件的行连续计数。)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/12959.html