sed高级命令

sed高级命令

sed模式空间

首先,应该明白模式空间的定义。模式空间就是读入行所在的缓存,sed对文本行进行的处理都是在这个缓存中进行的。这对接下来的学习是有帮助的。

在正常情况下,sed将待处理的行读入模式空间,脚本中的命令就一条接着一条的对该行进行处理,直到脚本执行完毕,然后该行被输出,模式空间请空;然后重复刚才的动作,文件中的新的一行被读入,直到文件处理完备。

但是,各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模式空间得到保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这个时候,sed设置了一些高级命令来满足用户的要求。

总的来说,这些命令可以划分为以下三类:

  1. N、D、P:处理多行模式空间的问题;
  2. H、h、G、g、x:将模式空间的内容放入存储空间以便接下来的编辑;
  3. :、b、t:在脚本中实现分支与条件结构。

多行模式空间的处理: 由于正则表达式是面向行的,因此,如若某个词组一不分位于某行的结尾,另外一部分又在下一行的开始,这个时候用grep等命令来处理就相当的困难。然而,借助于sed的多行命令N、D、P,却可以轻易地完成这个任务。

多行Next(N)命令是相对于next(n)命令的,后者将模式空间中的内容输出,然后把下一行读入模式空间,但是脚本并不会转移到开始而是从当前的n 命令之后开始执行;而前者则保存原来模式空间中的内容,再把新的一行读入,两者之间依靠一个换行符"\n"来分隔。在N命令执行后,控制流将继续用N命令以后的命令对模式空间进行处理。

值得注意的是,在多行模式中,特殊字符"^"和"$"匹配的是模式空间的最开始与最末尾,而不是内嵌"\n"的开始与末

sed命令

sed 包含了三个可用来处理多行文本的特殊命令,分别是:

  • Next 命令(N):将数据流中的下一行加进来创建一个多行组来处理。
  • Delete(D):删除多行组中的一行。
  • Print(P):打印多行组中的一行。
  • 注意,以上命令的缩写,都为大写。

N 多行操作命令

N 命令会将下一行文本内容添加到缓冲区已有数据之后(之间用换行符分隔),从而使前后两个文本行同时位于缓冲区中,sed 命令会将这两行数据当成一行来处理。

下面这个例子演示的 N 命令的功能:

[root@localhost ~]# cat data.txt 
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@localhost ~]# sed '/first/{ N ; s/\n/ / }' data.txt 
This is the header line.
This is the first data line. This is the second data line.
This is the last line.

在这个例子中,sed 命令查找含有单词 first 的那行文本。找到该行后,它会用 N 命令将下一行合并到那行,然后用替换命令 s 将换行符替换成空格。结果是,文本文件中的两行在 sed 的输出中成了一行。

下面这个例子就是用sed 匹配到header这一行的内容,再使用N将匹配到内容和下一行加入到模式空间;然后使用替换命令将line. 和换行 转换成and;最后结果就是将两行转换为了一行。

[root@localhost ~]# cat data4.txt 
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@localhost ~]# sed '
/header/{
N
s/line.\n/and /
}' data4.txt
This is the header and This is the first data line.
This is the second data line.
This is the last line.

$!N:

它是除了匹配到的最后一行不执行N命令,其他所有行都要执行N命令。

[root@localhost ~]# cat data5.txt 
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
This is and.
[root@localhost ~]# sed '
/line./{
$!N
s/\nThis/ and Thia/
}' data5.txt
This is the header line. and Thia is the first data line.
This is the second data line. and Thia is the last line.
This is and.

D 多行删除命令

sed 不仅提供了单行删除命令(d),也提供了多行删除命令 D,其作用是只删除缓冲区中的第一行,也就是说,D 命令将缓冲区中第一个换行符(包括换行符)之前的内容删除掉。

如:

[root@localhost ~]# cat data2.txt 
On Tuesday, the Linux System
Administrator's group meeting will be held.
All System Administrators should attend.
[root@localhost ~]# sed 'N ; /System\nAdministrator/D' data2.txt 
Administrator's group meeting will be held.
All System Administrators should attend.

文本的第二行被 N 命令加到了缓冲区,因此 sed 命令第一次匹配就是成功,而 D 命令会将缓冲区中第一个换行符之前(也就是第一行)的数据删除,所以,得到了如上所示的结果。

如下,它会删除数据流中出现在第一行前的空白行:

[root@localhost ~]# cat data3.txt 

This is the header line.
This is a data line.

This is the last line.
[root@localhost ~]# sed '/^$/{N ; /header/D}' data3.txt 
This is the header line.
This is a data line.

This is the last line.

sed会查找空白行,然后用 N 命令来将下一文本行添加到缓冲区。此时如果缓冲区的内容中含有单词 header,则 D 命令会删除缓冲区中的第一行。

d命令

d命令是删除当前模式空间内容(不在传至标准输出),并放弃之后的命令,并对新读取的内容,重头执行sed。

从data6.txt文件中取出奇数行

[root@localhost ~]# cat data6.txt 
This is 1   
This is 2   
This is 3   
This is 4   
This is 5
[root@localhost ~]# sed 'n;d' data6.txt 
This is 1   
This is 3   
This is 5

注释:读取1,执行n,得出2,执行d,删除2,得空,以此类推,读取3,执行n,得出4,执行d,删除4,得空,但是读取5时,因为n无法执行,所以d不执行。因无-n参数,故输出1\n3\n5

D命令

D命令是删除当前模式空间开端至\n的内容(不在传至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed。

从data6.txt文件中读取最后一行

[root@localhost ~]# cat data6.txt 
This is 1   
This is 2   
This is 3   
This is 4   
This is 5
[root@localhost ~]# sed 'N;D' data6.txt 
This is 5

注释:读取1,执行N,得出1\n2,执行D,得出2,执行N,得出2\n3,执行D,得出3,依此类推,得出5,执行N,条件失败退出,因无-n参数,故输出5

y命令

y命令的作用在于字符转换

将data6.txt文件内容大写

[root@localhost ~]# cat data6.txt 
This is 1   
This is 2   
This is 3   
This is 4   
This is 5
[root@localhost ~]# sed 'y/his/HIS/' data6.txt 
THIS IS 1   
THIS IS 2   
THIS IS 3   
THIS IS 4   
THIS IS 5

此外,如果需要对某个字符串进行大小写转换,则可使用如下方法

[root@localhost ~]# cat test 
This is a and a is 1   
This is b and b is 2   
This is c and c is 3   
This is d and d is 4   
This is e and e is 5
[root@localhost ~]# sed 's/\b[a-z]\b/\u&/g' test 
This is A and A is 1   
This is B and B is 2   
This is C and C is 3   
This is D and D is 4   
This is E and E is 5

h命令,H命令,g命令,G命令

h命令是将当前模式空间中内容覆盖至保持空间,H命令是将当前模式空间中的内容追加至保持空间

g命令是将当前保持空间中内容覆盖至模式空间,G命令是将当前保持空间中的内容追加至模式空间

将test文件中数字和字母互换,并将字母大写

[root@localhost ~]# cat test. 
h
{
s/.*is \(.*\) and .*/\1/
y/abcde/ABCDE/
G
s/\(.*\)\n\(.*is \).*\(and \).*\(is \)\(.*\)/\2\5 \3\5 \4\1/
} 
[root@localhost ~]# sed -f test. sed test
sed:无法读取 sed:没有那个文件或目录
This is 1    and 1    is A
This is 2    and 2    is B
This is 3    and 3    is C
This is 4    and 4    is D
This is 5 and 5 is E

注释:读取1,执行h,复制到保持空间,执行s,模式空间得到匹配到的字母a,然后执行y,将a转成A,执行G,追加保持空间内容到模式空间,得A\nThis is a and a is 1;执行s,重新排列,得出This is 1 and 1 is A;以此类推,得出结果。

这里需要注意的是匹配的内容中,空格一定要处理好,空格处理不对,会造成第二次s匹配错误,无法执行重新排列或排列错误

x命令

x命令是将当前缓存区和模式空间内容互换

posted @ 2021-09-17 01:16  Aimmi  阅读(209)  评论(0)    收藏  举报