Content #
单行next(n)命令会将数据流中的下一行移入sed编辑器的工作空间(称为模式空间)。多行版本的next(N)命令则是将下一行添加到模式空间中已有文本之后。
这样的结果是将数据流中的两行文本合并到同一个模式空间中。文本行之间仍然用换行符分隔,但sed编辑器现在会将两行文本当成一行来处理。
下面的例子演示了N命令的工作方式:
$ cat data2.txt
Header Line
First Data Line
Second Data Line
End of Data Lines
$
$ sed '/First/{ N ; s/\n/ / }' data2.txt
Header Line
First Data Line Second Data Line
End of Data Lines
$
sed编辑器脚本先查找含有单词First的那行文本,找到该行后,使用N命令将下一行与该行合并,然后用替换命令将换行符(\n)替换成空格。这样一来,两行文本在sed编辑器的输出中就成了一行。
如果要在数据文件中查找一个可能会分散在两行中的文本短语,那么这是一个很管用的方法。这里有个例子:
$ cat data3.txt
On Tuesday, the Linux System
Admin group meeting will be held.
All System Admins should attend.
Thank you for your cooperation.
$
$ sed 's/System Admin/DevOps Engineer/' data3.txt
On Tuesday, the Linux System
Admin group meeting will be held.
All DevOps Engineers should attend.
Thank you for your cooperation.
$
替换命令会在文本文件中查找特定的双词短语System Admin。如果短语是在一行中,那么事情就很好办,替换命令直接就能搞定。但如果短语分散在两行中,那么替换命令就没辙了。 N命令可以解决这个问题: $ sed ‘N ; s/System.Admin/DevOps Engineer/’ data3.txt On Tuesday, the Linux DevOps Engineer group meeting will be held. All DevOps Engineers should attend. Thank you for your cooperation. $ 用N命令将第一个单词所在行与下一行合并,即使短语内出现了换行,仍然可以查找到该短语。注意,替换命令在System和Admin之间用了点号模式(.)来匹配空格和换行符这两种情况。但如果点号匹配的是换行符,则删掉换行符会导致两行被合并成一行。这可能不是你想要的结果。要解决这个问题,可以在sed编辑器脚本中用两个替换命令,一个用来处理短语出现在多行中的情况,另一个用来处理短语出现在单行中的情况:
$ sed 'N
> s/System\nAdmin/DevOps\nEngineer/
> s/System Admin/DevOps Engineer/
> ' data3.txt
On Tuesday, the Linux DevOps
Engineer group meeting will be held.
All DevOps Engineers should attend.
Thank you for your cooperation.
$
第一个替换命令专门查找两个单词间的换行符,并将其放在了替换字符串中。这样就能在新文本的相同位置添加换行符了。但还有个不易察觉的问题。该脚本总是在执行sed编辑器命令前将下一行文本读入模式空间,当抵达最后一行文本时,就没有下一行可读了,这时N命令会叫停 sed编辑器。如果要匹配的文本正好在最后一行,那么命令就无法找到要匹配的数据:
$ cat data4.txt
On Tuesday, the Linux System
Admin group meeting will be held.
All System Admins should attend.
$
$ sed 'N
> s/System\nAdmin/DevOps\nEngineer/
> s/System Admin/DevOps Engineer/
> ' data4.txt
On Tuesday, the Linux DevOps
Engineer group meeting will be held.
All System Admins should attend.
$
System Admin文本出现在了数据流中的最后一行,但N命令会错过它,因为没有其他行可以读入模式空间跟这行合并。这个问题不难解决——将单行编辑命令放到 N命令前面,将多行编辑命令放到N命令后面,就像下面这样:
$ sed '
> s/System Admin/DevOps Engineer/
> N
> s/System\nAdmin/DevOps\nEngineer/
> ' data4.txt
On Tuesday, the Linux DevOps
Engineer group meeting will be held.
All DevOps Engineers should attend.
$
现在,查找单行中短语的替换命令在数据流的最后一行也能正常工作,N命令则负责短语出现在数据流中间的情况。
From #
Linux命令行与shell脚本编程大全