文章目录
1.1sed命令的语法
在看单个命令以前,需要回顾一下关于所有sed命令的两点语法。在上一个章中,我们介绍了其大部分内容。
行地址对于任何命令都是可选的。它可以使一个模式,被描述为由斜杠、行号或行寻址符号括住的正则表达式。大多数sed命令能接受由逗号分隔的两个地址,这两个地址,这两个地址用来标识行的范围。这些命令的语法格式为:
[address] command
有一些命令只接受单个行地址。它们不能应用于某个范围的行。它们的语法格式为:
[line-address] command
记住命令还可以用大括号进行分组以使其作用于同一个地址:
address {
command1
command2
command3
}
1.1.1案例
删除文件abc中的指定内容
[root@localhost test]# cat abc //查看一下文本内容
graphical
12345
# Keyboard layouts
[root@localhost test]# sed '/^graphical/d' abc //删除以graphical开头的内容
12345
# Keyboard layouts
//删除abc文件的第三行内容
[root@localhost test]# sed '3d' abc 3d代表删除abc文件的第三行
graphical
12345
1.2替换
我们已经讨论了替换命令的许多用法。下面是它的详细的用法:
[address] s/pattern/ rep | acement/flags
这里修饰替换的标志flags是:
n 1到512之间的一个数字,表示对文本模式中指定模式第n次出现的情况进行替换
g 对模式空间的所有出现的情况进行全局更改。而没有g是通常只有第一次出现的情况被取代。
p 打印模式空间的内容。
w file 将模式空间的内容写到文件file中。
注2: 使用GNU sed (版本2. 05)时不起作用。
替换命令应用于与address匹配的行。如果没有指定地址,那么就应用于Pattern匹配的所有行。如果正则表达式作为地址来提供,并且没有指定模式,那么替换命令匹配由地址匹配的内容。当替换命令是应用于同一个地址上的多个命令之一时,这可能会非常有用。
和地址不同的是,地址需要一个作为定界符的斜杠(/) ,而正则表达式可以用
任意字符来分隔,只有换行符除外。因此,如果模式包含斜杠,那么可以选择
另一个字符作为定界符,例如感叹号。
s!/usr/mail!/usr2/mail!
注意,定界符出现了3次而且在replacement之后是必需的。不管使用哪种定界符,如果它出现在正则表达式中者在替换文本中,那么就用反斜杠来转义它。
从前,计算机用固定长度的记录来存储文本。一行在出现许多字符(一般为80个)之后结束,然后开始下一行。数据中没有显式的字符来标记一行的结束和下一行的开始,每一行都有相同的(固定的)数量字符。现在的系统比较灵
活,它们使用特殊的字符(称为换行符(newline)) 标记行的结束。这样就允许行行的长度为任意(注3),
1.2.1 案例
替换绝对路径
//第一种方法
[root@localhost test]# echo '/usr/local/src' | sed 's/\/usr\/local\/src/\/user\/local\/src/' //虽然效果达到了但是看起来特别复杂
/user/local/src
//第二种方法
[root@localhost test]# echo '/usr/local/src' | sed 's#/usr/local/src#/user/local/src#' //把定界符改为#就可以发现简单不少
/user/local/src
数字表示很少使用,在这种情况下,正则表达式在一行上重复匹配,而只需要对其中某个位置的匹配进行替换。例如,某输入行也许包含tb1输入,也许包含多个制表位。假设每行有3个制表符,并且要用“>“替换第二个制表位,则可以使用下面的替换命令完成该功能:
s/./>/2
“.” 表示一个真正的制表符,而制表符在屏幕上是不可见的。如果输入是一行的文件,如下所示:
Col umn1●Co | umn2●Co I umn3●Co I umn4
对这个文件运行以上脚本所产生的输出如下:
Column1●Co I umn2>Co I umn3●Co I umn4
注意,如果没有数字标识,则替换命令只替换第一个制表符(因此“1“可以被看作是默认的数字标志)。
案例:
[root@localhost test]# cat abc //添加以下一行
graphical
12345
# Keyboard layouts
Column1 Column2 Column3 Column4
[root@localhost test]# sed 's/\t/>/2' abc //替换第二个tab为> 这里的\t代表着tab
graphical
12345
# Keyboard layouts
Column1 Column2>Column3 Column4
[root@localhost test]# sed 's/\t/\n/2' abc //换行
graphical
12345
# Keyboard layouts
Column1 Column2
Column3 Column4
1.3替换元字符
替换元字符是反斜杠()、“与”符号(&)和\n。反斜杠一般用于转义其他的元字符,但是他在替换字符串中也用于包含换行符。
我们可以对前面的示例做一些改动,用换行符取代每行上的第二个制表符。
s/*/\
/2
注意,在反斜杠后面不允许有空格。这个脚本产生下面的结果:
Col umn1●Co | umn2
Co | umn3●Co | umn4
另一个示例来自于将troff文件转换成Ventura Pub lisher的ASCII输入格.
式。它将下面的troff行:
Ah "Ma. jor Head ing"
转换成类似的Ventura Publisher 行:
@A HEAD = Ma jor Head ing
这个问题中的难点是这一行需要前后都有空行。这是一个编写多行替换字符串得问题。
/^\. Ah/ {
s/\.Ah */\
\
@AHEAD=/
s/"//g
s/$/\
/
}
1.3.1案例
[root@localhost test]# echo '.Ah "Major Heading"' > 1
[root@localhost test]# cat 1
.Ah "Major Heading"
[root@localhost test]# sed '/^\.Ah/{ //查找.Ah开头的内容 ,替换.Ah为@A HEAD = 把双引号去掉 以空行结尾,在换行
> s/\.Ah */\
> \
> @A HEAD = /
> s/"//g
> s/$/\
> /
> }
> ' 1
@A HEAD = Major Heading
//案例二
[root@localhost test]# cat 1 //添加以下一行
.Ah "Major Heading"
ORA Associates, Inc.
[root@localhost test]# sed -r "s/ORA/O'Reilly &/g" 1 //将1文件中的ORA替换成O'Reilly并打印
.Ah "Major Heading"
O'Reilly ORA Associates, Inc.
作为元字符,“与”符号(&) 表示模式匹配的范围,不是被匹配的行。可以使用“与”符号匹配一个单词并且用troff请求来包围它。下面的示例用点数请求包围一个单词:
s/UNIX/\\s- 2&\\s0/g
因为反斜杠也是替换字符串中的元字符,所以需要用两个反斜杠来输出一个反斜杠。替换字符串中的“&”表示“UNIX”。如果输入行为:
on the UNIX Operating System.
那么替换命令将产生:
on the \s- 2UNIX\s0 Operating System.
1.3.2 案例
[root@localhost test]# cat 1 //添加以下一行
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
[root@localhost test]# sed 's/UNIX/\\s-2&\\s0/g' 1 //替换
.Ah "Major Heading"
ORA Associates, Inc.
on the \s-2UNIX\s0 Operating System.
当正则表达式匹配单词的变化时,“ 与”符号特别有用。它允许指定一个可变的替换字符串,该字符串相当于匹配的内容与实际内容匹配的字符创。例如,假设要用圆括号括住文档中对已编号部分的任意交叉引用。换句话说,任意诸如“See Section 1.4" 或“See Section 12. 9”的引用都应该出现在圆括号中,如“(See Section 12.9)”。正则表达式可以匹配数字的不同组合,所以在替换字符串中可以使用“&”并括起所匹配的内容。
s/See Section [1-9][0-9]*\. [1-9][0-9]*/ (&)/
“与”符号用于在替换字符创中引用整个匹配内容。
现在,我们来看一种元字符,它用于选择被匹配的字符串的任意独立部分,并且在替换字符创中回调它。在sed中转义的圆括号括住正则表达式的任意部分
1.3.3案例
[root@localhost test]# cat 1 //添加最后两行
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
[root@localhost test]# sed 's/See Section [1-9][0-9]*\.[1-9][0-9]*/(&)/g' 1 //找到See Section 以及后面的数字,用括号括起来。
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
(See Section 1.4)
(See Section 12.9)
[root@localhost test]# sed -r 's/(.*) ([1-9][0-9]*\.[1-9][0-9]*)/\1\\fB\2\\fP/g' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section\fB1.4\fP
See Section\fB12.9\fP
我们可以使用类似的技术匹配行的部分内容并交换它们。例如,假如在一行上.有用冒号分隔的两个部分。我们可以匹配每个部分,把它们放置在转义的圆括号内并在替换过程交换它们。
$ cat test1
first : second
one: two
$ sed ’s/\(. *\):\(. *\)/\2:\1/’ test1
second:first
two:one.
重要的是可以按任意顺序回调保存的子串,并且可以多次调用,正如在下一个示例中将要看到的那样。
1.3.4转义案例
[root@localhost test]# cat 1 //添加最后两行
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost test]# sed -r 's/(.*):(.*)/\2:\1/g' 1 //将冒号两边的内容相转换
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
second:first
two:one
1.4 删除
前面已经展示了删除命令(d)的示例。它采用一个地址,如果行匹配这个地址就删除模式空间的内容。
删除命令还是一个可以改变脚本中的控制流的命令。这是因为一旦执行这个命令,那么在“空的”模式空间(注4)中就不会再有命令执行。删除命令会导致读取新输入行,而编辑脚本则从头开始新的一轮(这一行为和next命令的行
为相同,本章后面将介绍next命令)。
重要的是:如果某行匹配这个地址,那么就删除整个行,而不只是删除行中匹配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)。上一章展示了删除空行的命令:
注4:UNIX文件写道:“不允许在 被删除的行.上进一步操作”。R. I.P.
删除命令的另一个用处是去除某些troff请求、例如添加空格,分页和填充模式的打开和关闭:
/^\. sp/d
/^\. bp/d
. /^\. nf/d
/^\. fi/d
这些命令删除一个完整的行。例如,第一个命令删除行“.sp 1”或. sp.03v"。
删除命令可以用于删除一个范围内的行。在上一章中,有一个通过删除宏. TS和. TE之间的行来删除文件中的所有表格的示例。还有一个删除命令(D)用于删除多行模式空间的一部分
1.4.1 删除案例
[root@localhost test]# sed '/^.Ah/d' 1 //删除以.Ah开头的行
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
1.5 追加,插入和更改
追加(a)、插入(i)和更改©命令提供了通常在交互式编辑器(例如vi)中所选的编辑功能。你会奇怪地发现、可以使用这些相同的命令在非交互编辑器中“输入”文本。这些命令的语法在sed中不常用,因为它们必须在多.行上来指定。语法如下:
追加[line-address]a\
text
插入[| ine-address]i\
text
更改[address]c\
text
插入命令将所提供的文本放置在模式空间的当前行之前。追加命令将文本放置在当前行之后。更改命令用所提供的文本取代模式空间的内容。
这些命令中的每一个都要求后面跟一个反斜杠用于转义第一个行尾。text 必须从下一行开始。要输入多行文本,每个连续的行都必须用反斜杠结束,最后一行例外。例如,下面的插入命令在匹配“<Larry’’ s Address>” 行的地方插入两行文本:
/<Larry’s Address>/i\
4700 Cross Court\
French Lick,IN
而且,如果文本包含一个字面的反斜杠,要再添加一个反斜杠来转义它
追加命令和插入命令只应用于单个行地址,而不是一个范围内的行。然而,更改命令可以处理一一个范围内的行。在这种情况下,它用一个文本备份取代所有被寻址的行。换句话说,它删除这个范围中的所有行,但是提供的文本只被输出一次。例如,当下面的脚本在包含邮件消息的文件上运行时:
/^From /,/^ $/c\
<Mail Header Removed>
删除整个邮件消息头并用行“”取代它。注意,当更改命令作为一组命令之一被封闭在大括号中并作用于一个范围内的行时,它将具有相反的功能。例如,下面的脚本:
/^From /,/^$/{
s/^ From //p
c\
<Mail Header Removed>
}
将对这个范围内的每行输出“” 。所以,当前面的示例输出文本一次时,这个示例会输出10次,如果在这个范围内有10行的话。
更改命令清除模式空间,它在模式空间中与删除命令有同样的效果。脚本中在更改命令之后的其他命令没有被提供。
插入命令和追加命令不影响模式空间的内容。提供的文本将不匹配脚本中后续命令中的任何地址,那些命令也不影响该文本。不管什么更改改变了模式空间,所提供的文本仍然会正确地输出。当默认的输出受到抑制时也是这样一所提供的文本将被输出,即使模式空间不是那样的。而且,所提供的文本不影响sed的内部行计数器。
1.5.1 追加案例
[root@localhost test]# sed '1 a abc 123' 1 //在1文件的第一行后追加一行abc 123
.Ah "Major Heading"
abc 123
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost test]# sed '/See.*[1-9][0-9]\.[0-9]/aabc' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
abc
first:second
one:two
1.5.2 插入案例
[root@localhost test]# sed '1i nihao' 1 //在1文件的第一行的前面添加一行内容
nihao
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost test]# sed '/^\.Ah/i hello world' 1 //在1文件中找到.Ah开头的并在前面插入一行hello world
hello world
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
1.5.3 更改案例
[root@localhost test]# sed '/.Ah/c \ hello java' 1 //在1文件中找到.Ah并把这一行更改成hello java
hello java
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost test]# sed '/^\.Ah/,/on /cabc' 1 //在1文件中找到以.Ah开头的并把这一行更改成abc
abc
See Section 1.4
See Section 12.9
first:second
one:two
1.6 转换
转换命令是特有的,不仅因为它在所有的sed命令中拥有最小的肋记符。这个命令按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符(注9)。它的语法如下:
[address]y/ abc/xyz/
替换根据字符的位置来进行。因此,它没有“词”的概念。这样,在该行.上的任何地方的“a”都被换成了“x”,而不管它后面是否跟有“b”。这个命令的一个可能的用处是用大写字母替换对应的小写字母,
y/ abcdefghi jk Imnopqr stuvwxyz/ ABCDEFGHI JKLMNOPQRSTUVWXYZ/
这个命令影响整个模式空间的所有内容。如果想在输入行上转换单个单词,那么通过使用保持空间可以完成。参见第六章有关如何使用保持空间的详介绍(大致过程是:输出更改单的那一行之前的所有行,删除这些行,将单词后面的行复制到保持空间,转换这个单词,然后将保持空间的内容追加到模式空间)
1.6.1转换案例
[root@localhost test]# sed '1y/jao/123/' 1 //将1文件中第一行中出现的字母j a o 替换成 1 2 3 (注意这里不是单词,而是一个一个的字母)
.Ah "M213r He2ding"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
1.7 打印
打印命令§ 输出模式空间的内容。它既不清除模式空间也不改变脚本中的控制流。然而,它频繁地用在改变流控制的命令(d,N,b) 之前。除非抑制(-n)默认的输出,否则打印命令将输出行的重复复制。当抑制默认的输出或者当通过程序的流控制来避免到达脚本的底部时,可能会使用它。
下面我们看一个如何使用打印命令来进行调试的脚本。它用于显示在发生任意改变之前行是什么样的。
#在行改变之前和之后打印行
/^\. Ah/{
p
s/ "//g
s/^\.Ah //p
}
注意,打印标志被提供给替换命令。替换命令的打印标志不同于打印命令,因为它是以成功的替换为条件的。
下面是运行.上面脚本的一个例子:
$ sed -f sed. debug ch05
. Ah "Comment”
Comment
Ah " Substitut ion"
Substitut ion .
Ah "De lete"
De lete
Ah "Append,Insert and Change "
Append,Insert and Change
.Ah "List'
List
每个受影响的行都被打印了两次。
我们将在下一章看到打印命令的其他示例。在下一章还会看到多行打印命令
§。
1.7.1 打印案例
[root@localhost test]# cat 2 //写一个这样的文本
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"
[root@localhost test]# sed '/^\.Ah/{p;s/"//g;s/^\.Ah //}' 2
.Ah "Comment"
Comment
.Ah "Substitution"
Substitution
.Ah "Delete"
Delete
.Ah "Append, Insert and Change"
Append, Insert and Change
.Ah "List"
List
1.8 打印行号
跟在地址后面的等号(=) 打印被匹配的行的行号。除非抑制行的自动输出,行号和行本身将被打印。它的语法如下:
[1 ine-address]=
这个命令不能对一个范围内的行进行操作。
程序员也许用该命令打印源文件中的某些行。例如,下面的脚本打印行号和行
本身,这些行都包含后面跟有字符串“if” 的制表符。脚本如下:
#n打印具有if 语句的行号和行
/if/{
=
p
}
1.8.1打印行号案例
[root@localhost test]# sed -n '/Comment/{=;p}' 2 //在文件查找Comment内容打印执行结果并且抑制默认打印 此处的1代表Commnet在第一行
1
.Ah "Comment"
2.高级sed命令
2.1多行模式空间
在前面正则表达式的讨论中,我们强调模式匹配是面向行的。像grep这样的程序尝试在单个输入行.上匹配一个模式。这就使它很难匹配一个在一行的结尾处开始。并在下一行的开始处结束的短语。其他一-些模式只有当在多行上重复时才有意义。
sed能查看模式空间的多个行。这就是允许匹配模式扩展到多行上。在本节中,我们将来看一下创建多行模式空间并处理它的内容的命令。这里的3个多行命令(N、 D、P)对应于上一章出现的小写字母的基本命令(n、d、p)。例如,删除命令(D) 是删除命令(d)的多行形式。区别是: d删除模式空间的内容,D只删除多行模式空间的第一行。
2.1.1 追加下一行
多行Next (N) 命令通过读取新的输入行,并将它添加到模式空间的现有内容之后来创建多行模式空间。模式空间最初的内容和新的输入行之间用换行符分隔。在模式空间中嵌入的换行符可以利用转义序列“\n”来匹配。在多行模式空间中,元字符“^”匹配空间中的第一个字条,而不匹配换行符后面的字符。同样,“$” 只匹配模式空间中最后的换行符,而不匹配任何嵌入的换行符。在执行next命令之后,控制将被传递给脚本中的后续命令。
2.1.2 案例
[root@localhost ~]# vim abc
[root@localhost ~]# cat abc //写一个跟我一样的文件
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
[root@localhost ~]# sed '/Operator$/{N;s/Owner and Operator\nGuide/installation Guide/g}' abc //匹配以Operator结尾的行以及它的下一行把Owner and Operator和一下行的Guide替换成installation Guide
Consult Section 3.1 in the installation Guide for a description of the tape driveschaoz
available on your system.
[root@localhost ~]# sed -n '/Operator$/{N;p}' abc //关闭默认打印并匹配以Operator结尾的行以及它的下一行并且将效果打印出来 操作的文件是abc
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
[root@localhost ~]# sed -n '/Operator$/{N;s/Owner and Operator\nGuide/installation Guide/g ;p}' abc //关闭默认打印并匹配以Operator结尾的行以及它的下一行把Owner and Operator和一下行的Guide替换成installation Guide 并且打印效果
Consult Section 3.1 in the installation Guide for a description of the tape drives
//将abc文件替换成以下内容
[root@localhost ~]# > abc
[root@localhost ~]# vim abc
[root@localhost ~]# cat abc
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
Look in the Owner and Operator Guide shipped with your system.
Two manuals are provided inc luding the Owner and
Operator Guide and the User Gui de.
The Owner and Operator Guide is shipped with your system.
[root@localhost ~]# sed 's/Owner and Operator Guide/installation Guide/g;/Owner/{N;s/ *\n/ /g;s/Owner and Operator Guide */installation Guide\n/g}' abc //将abc文件中Owner and Operator Guide替换成installation Guide 匹配Owner这一行以及下一行 将换行去掉将Owner and Operator Guide替换成installation Guide
Consult Section 3.1 in the installation Guide
for a description of the tape drives
available on your system.
Look in the installation Guide shipped with your system.
Two manuals are provided inc luding the installation Guide
and the User Gui de.
The installation Guide is shipped with your system.
[root@localhost ~]# sed 's/Owner and Operator Guide/installation Guide/g' abc 将Owner and Operator Guide替换成installation Guide
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
Look in the installation Guide shipped with your system.
Two manuals are provided inc luding the Owner and
Operator Guide and the User Gui de.
The installation Guide is shipped with your system.
[root@localhost ~]# sed -n 's/Owner and Operator Guide/installation Guide/g;/Owner/p' abc //取消默认打印将Owner and Operator Guide替换成installation并打印结果
Consult Section 3.1 in the Owner and Operator
Two manuals are provided inc luding the Owner and
[root@localhost ~]# sed -n 's/Owner and Operator Guide/installation Guide/g;/Owner/{N;p}' abc //将匹配到的下一行追加到模式空间
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
Two manuals are provided inc luding the Owner and
Operator Guide and the User Gui de.
[root@localhost ~]# sed -n 's/Owner and Operator Guide/installation Guide/g;/Owner/{N;s/ *\n/ /g;p}' abc //将Owner and Operator Guide替换成installation Guide 并将换行替换成空格
Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives
Two manuals are provided inc luding the Owner and Operator Guide and the User Gui de.
[root@localhost ~]# sed -n 's/Owner and Operator Guide/installation Guide/g;/Owner/{N;s/ *\n/ /g;s/Owner and Operator Guide */installation Guide\n/g;p}' abc 将Owner and Operator Guide 替换成installation Guide\n 将换行变为空格 然后将Owner and Operator Guide * 替换为installation
Consult Section 3.1 in the installation Guide
for a description of the tape drives
Two manuals are provided inc luding the installation Guide
and the User Gui de.
2.2 多行删除
删除命令(d) 删除模式空间的内容并导致读入新的输入行,从而在脚本的顶端.重新使用编辑方法。删除命令(D) 稍微有些不同:它删除模式空间中直到第一个嵌入的换行符的这部分内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用于模式空间剩余的内容,我们可以编写一个实现查找一系列空行并输出单个空行的脚本,以看看它们之间的区别。下面的语句使用了删除命令(d):
2.2.1案例
[root@localhost ~]# sed '/^$/{N;/^\n$/d}' abc
This line is followed by 1 blank line.
This line is followed by 2 blank lines.
This line is followed by 3 blank lines.
This line is followed by 4 b lank lines.
This is the end.
[root@localhost ~]# sed -n '/^$/{N;p}' abc //关闭默认打印匹配空行然后将匹配到的空行追加到模式空间
This line is followed by 2 blank lines.
This line is followed by 4 b lank lines.
[root@localhost ~]# sed -n '/^$/{N;/^\n$/d;p}' abc //关闭默认打印匹配空行以及下一行并删除
This line is followed by 2 blank lines.
This line is followed by 4 b lank lines.
2.3 多行打印
多行打印(Print) 命令与小写字母的print命令稍有不同。该命令输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。在执行完脚本的最后一个命令之后,模式空间的内容自动输出(-n 选项或#n抑制这个默认的动作)。因
此,当默认的输出被抑制或者脚本中的控制流更改,以至不能到达脚本的底部时,需要使用打印命令(P 或p) .Print 命令经常出现在Next命令之后和Delete命令之前。这3个命令能建立一个输入/输出循环,用来维护两行的模
式空间,但是一次只输出一行。这个循环的目的是只输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。创建多行模式空间以匹配第一行结尾处的“UNIX" 和第二行开始处的“System”
。
2.3.1 案例
//将abc文件更改为如下内容
[root@localhost ~]# > abc
[root@localhost ~]# vim abc
[root@localhost ~]# cat abc
Here are examples of the UNIX
System. Where UNIX
System appears,it should be the UNIX
Operating System.
[root@localhost ~]# sed '/UNIX$/{N;/\nSystem/{s// Operating &/g;P;D}}' abc
Here are examples of the UNIX Operating
System. Where UNIX Operating
System appears,it should be the UNIX
Operating System.
[root@localhost ~]# sed -n '/UNIX$/{N;p}' abc
Here are examples of the UNIX
System. Where UNIX
System appears,it should be the UNIX
Operating System.
[root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{p}}' abc
Here are examples of the UNIX
System. Where UNIX
[root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{s// Operating &/g;p}}' abc
Here are examples of the UNIX Operating
System. Where UNIX
[root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{s// Operating &/g;P}}' abc
Here are examples of the UNIX Operating
[root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{s// Operating &/g;P;D}}' abc
Here are examples of the UNIX Operating
System. Where UNIX Operating
2.4 包含那一行
模式空间是容纳当前输入行的缓冲区。还有一个称为保持空间(hold space)的顶留(set-aside) 缓冲区。模式空间的内容可以复制到保持空间,而且保持空间的内容也可以复制到模式空间。有一组命令用于在保持空间和模式空间之
间移动数据。保持空间用于临时存储。单独的命令不能寻址保持空间或者更改它的内容。保持空间最常的用途是,当改变模式空间中的原始内容时,用于保留当前输入行的副本。影响模式空间的命令有:
2.4.1 案例
//将abc文件修改为以下内容
[root@localhost ~]# > abc
[root@localhost ~]# vim abc
[root@localhost ~]# cat abc
1
2
11
22
111
222
[root@localhost ~]# sed -n '/1/{h;d};/2/{G};p' abc //将匹配到的1放到保持空间然后再取出追加到2的后面
2
1
22
11
222
111
[root@localhost ~]# sed -n '/1/{h;d};p' abc 关闭默认打印,将1匹配到然后放到保持模式并删除,再打印出效果
2
22
222