高级命令分成了3个组:
- 处理了多行模式空间(N、D、P)。
- 采用保持空间来保存模式空间的内容并使它可用于后续的命令(H,h,Gg.x)。
- 编写使用分支和条件指令的脚本来更改控制流(:,b,t)。
与模式空间和暂存空间(hold space)相关的命令:
- n 输出模式空间行,读取下一行替换当前模式空间的行,执行下一条处理命令而非第一条命令。
- N 读入下一行,追加到模式空间行后面,此时模式空间有两行。
- h 把模式空间里的行拷贝到暂存空间。
- H 把模式空间里的行追加到暂存空间。
- g 用暂存空间的内容替换模式空间的行。
- G 把暂存空间的内容追加到模式空间的行后。
- x 将暂存空间的内容于模式空间里的当前行互换。
- ! 对所选行以外的所有行应用命令。
注意: 暂存空间里默认存储一个空行。
命令N
追加下一行
多行Next (N)命令通过读取新的输入行,并将它添加到模式空间的现有内容之后来创建多行模式空间。模式空间最初的内容和新的输入行之间用换行符分隔。在模式空间中嵌入的换行符可以利用转义序列“\n"来匹配。在多行模式空间中,元字符“"”匹配空间中的第一个字条,而不匹配换行符后面的字符。
同样, “$”只匹配模式空间中最后的换行符,而不匹配任何嵌入的换行符。在执行next命令之后,控制将被传递给脚本中的后续命令。
Next命令与next命令不同, next输出模式空间的内容,然后读取新的输入行。next命令不创建多行模式空间。
[root@ansible ~]# cat test.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@ansible ~]# sed -n '/first/p' test.txt
This is the first data line.
[root@ansible ~]# sed -n '/first/N;p' test.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@ansible ~]# sed '/first/N;s/\n//' test.txt
This is the header line.
This is the first data line.This is the second data line.
This is the last line.
[root@ansible ~]# sed -e '/first/{N;s/\n//;N;s/\n//}' test.txt
This is the header line.
This is the first data line.This is the second data line.This is the last line.
命令D
Delete(D):删除多行组中的一行。
sed 不仅提供了单行删除命令(d),也提供了多行删除命令 D,其作用是只删除缓冲区中的第一行,也就是说,D 命令将缓冲区中第一个换行符(包括换行符)之前的内容删除掉。
[root@ansible ~]# cat test.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@ansible ~]# sed '/^$/{N;/^\n$/d}' test.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@ansible ~]# sed '/^$/{N;/^\n$/D}' test.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
命令H或h、G或g、x、b
命令 | 缩写 | 功能 |
---|---|---|
Hold | h或H | 将模式空间的内容复制或追加到保持空间 |
Get | g或G | 将保持空间的内容复制或追加到模式空间 |
Exchange | x | 交换保持空间和模式空间的内容 |
这些命令中的每一条都可以利用一个地址来指定一行或行范围。Hole (h, H)命令将数据移至保持空间、而get (g.G)命令将保持空间的数据移回到模式空间。
同一命令的小写字母和大写字母之间的差别是,小字字母命令改写目的缓存区的内容,而大写字母命令追加缓存区的现有内容。
Hold命令用模式空间的内容取代保持空间的内容。get命令用保持空间的内容取代模式空间的内容。
Hole命令在保持空间的内容之后放置一个换行符,且后面跟随模式空间的内容(即使保持空间是空的,换行符也被追加到保持空间中) 。Get命令模式空间的内容之后放置一个换行符,且后面跟随保持空间的内容。
颠倒以2开始的行和以4开始的行的顺序
[root@ansible ~]# cat test
2
4
22
44
222
444
[root@ansible ~]# cat sednew
/2/{
h
d
}
/4/{
G
}
[root@ansible ~]# sed -f sednew test
4
2
44
22
444
222
[root@ansible ~]# sed '2h;3H;5g' test
2
4
22
44
4
22
444
b 分支命令
通常,sed 程序的执行过程会从第一个脚本命令开始,一直执行到最后一个脚本命令(D 命令是个例外,它会强制 sed 返回到脚本的顶部,而不读取新的行)。sed 提供了 b 分支命令来改变命令脚本的执行流程,其结果与结构化编程类似。
[root@ansible ~]# cat test
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@ansible ~]# sed '{2,3b ; s/This is/Is this/ ; s/line./test?/}' test
Is this the header test?
This is the first data line.
This is the second data line.
Is this the last test?