Linux之sed进阶

1.sed &用法

1.1. sed & 用法

[root@ecs-76840553 sed]# cat 2
You are beautiful
hello world hello
alknlaknqlw hello hello
hello world 
[root@ecs-76840553 sed]# cat 2| sed -r 's/hello/(&)/'
You are beautiful
(hello) world hello
alknlaknqlw (hello) hello
(hello) world 
[root@ecs-76840553 sed]# cat 2| sed -r 's/hello/(&)/g'
You are beautiful
(hello) world (hello)
alknlaknqlw (hello) (hello)
(hello) world 
[root@ecs-76840553 sed]# 

讲解:& 符号代表的是你前面的匹配的内容。sed 是以行为单位的,默认匹配行的第一个,全部匹配需要加上g。

 2.sed改变执行流程命令

2.1 sed b 命令

语法:

[address]b [label]

address 参数决定了哪些行的数据会触发分支命令,label 参数定义了要跳转到的位置。需要注意的是,如果没有加 label 参数,跳转命令会跳转到脚本的结尾。例如:

[root@ecs-76840553 sed]# cat lable.txt 
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@ecs-76840553 sed]# sed '{2,3b; s/This is/Is this/ ; s/line./test?/}' lable.txt 
Is this the header test?
This is the first data line.
This is the second data line.
Is this the last test?
[root@ecs-76840553 sed]#

可以看到,因为 b 命令未指定 label 参数,因此数据流中的第2行和第3行并没有执行那两个替换命令。如果我们不想直接跳到脚本的结尾,可以为 b 命令指定一个标签(也就是格式中的 label,最多为 7 个字符长度)。在使用此该标签时,要以冒号开始(比如 :label2),并将其放到要跳过的脚本命令之后。这样,当 sed 命令匹配并处理该行文本时,会跳过标签之前所有的脚本命令,但会执行标签之后的脚本命令。

[root@ecs-76840553 sed]# sed -r '{2,3b lable s/This is/Is this/ ;:lable s/line./test?/}' lable.txt 
Is this the header test?
This is the first data test?
This is the second data test?
Is this the last test?
[root@ecs-76840553 sed]# 
[root@ecs-76840553 sed]# sed -r '{/second/b lable s/This is/Is this/ ;:lable s/line./test?/}' lable.txt 
Is this the header test?
Is this the first data test?
This is the second data test?
Is this the last test?
[root@ecs-76840553 sed]# sed -r '{/three/b lable s/This is/Is this/ ;:lable s/line./test?/}' lable.txt 
Is this the header test?
Is this the first data test?
Is this the second data test?
Is this the last test?
[root@ecs-76840553 sed]# 

在以上两个例子中,如果文本行中出现了 second,程序的执行会直接跳到 lable 标签之后的脚本行。如果分支命令的模式没有匹配three,sed 会继续执行所有的脚本命令。b 分支命令除了可以向后跳转,还可以向前跳转。

[root@ecs-76840553 sed]# echo "This, is, a, test, to, remove, commas." |sed -n '{:start;  s/,//1p ;/,/b start}'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
[root@ecs-76840553 sed]# 

在这个例子中,当缓冲区中的行内容中有逗号时,脚本命令就会一直循环执行,每次迭代都会删除文本中的第一个逗号,并打印字符串,直至内容中没有逗号。

 2.2  sed t 命令

类似于 b 分支命令,t 命令也可以用来改变 sed 脚本的执行流程。t 测试命令会根据 s 替换命令的结果,如果匹配并替换成功,则脚本的执行会跳转到指定的标签;反之,t 命令无效。测试命令使用与分支命令相同的格式:

[address]t [label]
[root@ecs-76840553 sed]# cat lable.txt | sed -r 's/first/two/;t tt; s/line/2222/;:tt'
This is the header 2222.
This is the two data line.
This is the second data 2222.
This is the last 2222.
[root@ecs-76840553 sed]# 

匹配不成功例子:

[root@ecs-76840553 sed]# cat lable.txt | sed -r 's/pipei/two/;t tt; s/line/2222/;:tt'
This is the header 2222.
This is the first data 2222.
This is the second data 2222.
This is the last 2222.

 3.sed保持空间

sed 命令处理的是缓冲区中的内容,其实这里的缓冲区,应称为模式空间。值得一提的是,模式空间并不是 sed 命令保存文件的唯一空间。sed 还有另一块称为保持空间的缓冲区域,它可以用来临时存储一些数据。下表列出了 5 条可用来操作保持空间的命令。

命令 功能
h 将模式空间中的内容复制到保持空间
H 将模式空间中的内容附加到保持空间
g 将保持空间中的内容复制到模式空间
G 将保持空间中的内容附加到模式空间
x 交换模式空间和保持空间中的内容

通常,在使用 h 或 H 命令将字符串移动到保持空间后,最终还要用 g、G 或 x 命令将保存的字符串移回模式空间。保持空间最直接的作用是,一旦我们将模式空间中所有的文件复制到保持空间中,就可以清空模式空间来加载其他要处理的文本内容。由于有两个缓冲区域,下面的例子中演示了如何用 h 和 g 命令来将数据在 sed 缓冲区之间移动。

[root@localhost ~]# cat data2.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 -n '/first/{h;p;n;p;g;p;}' data2.txt
This is the first data line.
This is the second data line.
This is the first data line.

 这个例子的运行过程是这样的:

  • sed脚本命令用正则表达式过滤出含有单词first的行;
  • 当含有单词 first 的行出现时,h 命令将该行放到保持空间;
  • p 命令打印模式空间也就是第一个数据行的内容;
  • n 命令提取数据流中的下一行(This is the second data line),并将它放到模式空间;
  • p 命令打印模式空间的内容,现在是第二个数据行;
  • g 命令将保持空间的内容(This is the first data line)放回模式空间,替换当前文本;
  • p 命令打印模式空间的当前内容,现在变回第一个数据行了。
posted @ 2022-09-16 15:21  家乐福的搬砖日常  阅读(57)  评论(0编辑  收藏  举报