sed语句应用

sed语句应用

基本sed命令

替换
替换命令应用于与 address 匹配的行。如果没有指定地址,那么就应用于Pattern 匹配的所有行。如果正则表达式作为地址来提供,并且没有指定模式,那么替换命令匹配由地址匹配的内容。当替换命令是应用于同一个地址上的多个命令之一时,这可能会非常有用。

&:用正则表达式匹配的内容进行替换

[root@localhost ~]# cat e
023-123456
0213-1313213
012-4132413
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
[root@localhost ~]# sed -E 's/(\(?0[0-9]{2,3}\)?-?)?[0-9]{5,8}/电话: &/g' e
电话: 023-123456
电话: 0213-1313213
电话: 012-4132413
电话: 0202-321321
电话: 081-312231
1232
电话: 121212-电话: 321321312321
电话: 912121-电话: 3214124214
rkwj-电话: 21312cfad

\n: 匹配第n个字串(n是一个数字),这个字串以前在pattern中用“(“和“)“指定。

: 转义符,当在替换部分包含“与“符号(&),反斜杠()和替换命令的定界符时可用\转义它们。另外,它用于转义换行符并创建多行replacement字符串。

[root@localhost ~]# cat f
+
!
?
\
[root@localhost ~]# grep '+' f
+
[root@localhost ~]# grep '!' f
!
[root@localhost ~]# grep '?' f
?
[root@localhost ~]# grep '\\' f
\
替换元字符
替换元字符是反斜杠(\)、“与”符号(&)和\n。反斜杠一般用于转义其他的元字符,但是他在替换字符串中也用于包含换行符。注意,在反斜杠后面不允许有空格

一个替换示例

将.Ah "Major Heading"替换成@A HEAD = Major Heading
[root@localhost ~]# cat g
.Ah "Major Heading"
[root@localhost ~]# sed '/^\.Ah/{s/\.Ah */@A HEAD = /;s/"//g}' g
@A HEAD = Major Heading
删除
它采用一个地址,如果行匹配这个地址就删除模式空间的内容。
删除命令还是一个可以改变脚本中的控制流的命令。这是因为一旦执行这个命令,那么在“空的”模式空间中就不会再有命令执行。删除命令会导致读取新输入行,而编辑脚本则从头开始新的一轮。
重要的是:如果某行匹配这个地址,那么就删除整个行,而不只是删除行中匹配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)。
删除命令的另一个用处是去除某些troff 请求、例如添加空格,分页和填充模式的打开和关闭。

删除命令(d)

删除两行之间的空格示例
[root@localhost ~]# cat g
.Ah "Major Heading"



.Ah "Major Heading"
[root@localhost ~]# sed '/^$/d' g
.Ah "Major Heading"
.Ah "Major Heading"

追加、插入和更改
追加(a)、插入(i)和更改(c)命令提供了通常在交互式编辑器(例如vi)中所选的编辑功能。你会奇怪地发现、可以使用这些相同的命令在非交互编辑器中“输入”文本。这些命令的语法在sed中不常用,因为它们必须在多行上来指定。
追加示例
[root@localhost ~]# cat e
023-123456
0213-1313213
012-4132413
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
第一种就是输入在哪行的后面添加几行就是几a
[root@localhost ~]# sed '3adawda' e
023-123456
0213-1313213
012-4132413
dawda
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
第二种就是直接输入匹配的那行添加
[root@localhost ~]# sed '/012-4132413/adawda' e
023-123456
0213-1313213
012-4132413
dawda
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
插入示例
[root@localhost ~]# cat e
023-123456
0213-1313213
012-4132413
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
直接写匹配的行数
[root@localhost ~]# sed '3idkakd' e
023-123456
0213-1313213
dkakd
012-4132413
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
直接写匹配的指定内容
[root@localhost ~]# sed '/0213-1313213/iidkakd' e
023-123456
idkakd
0213-1313213
012-4132413
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
更改示例
[root@localhost ~]# cat e
023-123456
0213-1313213
012-4132413
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
[root@localhost ~]# sed '3c321' e
023-123456
0213-1313213
321
0202-321321
081-312231
1232
121212-321321312321
912121-3214124214
rkwj-21312cfad
转换
转换命令是特有的,不仅因为它在所有的sed 命令中拥有最小的肋记符。这个命令按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符。
转换示例
全部转换
[root@localhost ~]# cat b
aaa
aaaa
aaaaa
abc
abbc
abbbc
[root@localhost ~]# sed 'y/abc/ABC/' b
AAA
AAAA
AAAAA
ABC
ABBC
ABBBC
还可以指定转换哪一行
[root@localhost ~]# sed '3y/a/A/' b
aaa
aaaa
AAAAA
abc
abbc
abbbc
打印
打印命令(p)输出模式空间的内容。它既不清除模式空间也不改变脚本中的控制流。然而,它频繁地用在改变流控制的命令(d,N, b)之前。除非抑制(-n)默认的输出,否则打印命令将输出行的重复复制。当抑制默认的输出或者当通过程序的流控制来避免到达脚本的底部时,可能会使用它。
[root@localhost ~]# cat d
13487643389
12382498329
19384983292
19393489834
18349844893
13984384399
doiadaowijf
1291380130192390
39183913131381983
-n只显示匹配的内容
[root@localhost ~]# sed -n '/12382498329/p' d
12382498329
打印行号
跟在地址后面的等号(=)打印被匹配的行的行号。除非抑制行的自动输出,行号和行本身将被打印。
[root@localhost ~]# cat d
13487643389
12382498329
19384983292
19393489834
18349844893
13984384399
doiadaowijf
1291380130192390
39183913131381983
[root@localhost ~]# sed '/12382498329/=' d
13487643389
2
12382498329
19384983292
19393489834
18349844893
13984384399
doiadaowijf
1291380130192390
39183913131381983
下一步
下一步(next)命令(n)输出模式空间的内容,然后读取输入的下一行,而不用返回到脚本的顶端。
next命令改变了正常的流控制,直到到达脚本的底部才会输出模式空间的内容,它总是在读入新行之后从脚本的顶端开始。实际上,next命令导致输入的下一行取代横穿空间中的当前行。脚本中的后续命令应用于替换后的行,而不是当前行。如果没有抑制默认输出,那么在替换发生之前会打印当前行
下面我们来看next命令的示例,在这个例子中,当空行跟随一个匹配模式的行时,则删除该空行。在这种情况中,假设作者已经在节标题宏(.H1)之后插入一个空行。我们想要删除这个窄而不是删除文件中所有的空行。
示例:
[root@localhost ~]# cat h
.H1 "On Egypt"

Napoleon,pointing to the Pyramids,said to his troops :
"Soldiers,forty centuries have their eyes upon you."

hhhhh
[root@localhost ~]# sed '/^\.H1/{n;/^$/d}' h
.H1 "On Egypt"
Napoleon,pointing to the Pyramids,said to his troops :
"Soldiers,forty centuries have their eyes upon you."

hhhhh

退出
退出命令(q)会使sed停止读取新的输入行(并停止将它们发送到输出)。
它只适用于单行的地址。一旦找到需要匹配的行,那么脚本就结束
只能从前向后打印
[root@localhost ~]# cat b
aaa
aaaa
aaaaa
abc
abbc
abbbc
[root@localhost ~]# sed '4q' b
aaa
aaaa
aaaaa
abc

高级sed命令

高级命令分成了3个组:

1.处理了多行模式空间(N、D、P)。

2.采用保持空间来保存模式空间的内容并使它可用于后续的命令(H、h、G、g、x)。

3.编写使用分支和条件指令的脚本来更改控制流(:、b、 t) 。

通常,一行被读入模式空间并且用脚本中的每个命令(一个接一个地)应用于那一行。当达到脚本的底部时,输出这一行并且清空模式空间。然后新行被读入模式空间,并且控制被转移回脚本的顶端。这是sed脚本中正常的控制流。

脚本由于各种原因中断或暂停了正常的控制流。它们也许想阻止脚本中的命令被执行,某些特定的情况除外,或者阻止模式空间的内容被清除。更改控制流会使脚本更加难以阅读和理解。

多行模式空间

在前面正则表达式的讨论中,我们强调模式匹配是面向行的。像grep这样的程序尝试在单个输入行上匹配一个模式。这就使它很难匹配一个在一行的结尾处开始。并在下一行的开始处结束的短语。其他一些模式只有当在多行上重复时才有意义。

sed 能查看模式空间的多个行。这就是允许匹配模式扩展到多行上。我们将来看一下创建多行模式空间并处理它的内容的命令。这里的3个多行命令(N、D、P)对应于小写字母的基本命令(n、d、p)。例如,删除命令(D)是删除命令(d)的多行形式。区别是:d删除模式空间的内容,D只删除多行模式空间的第一行。

追加下一行

多行Next(N)命令通过读取新的输入行,并将它添加到模式空间的现有内容之后来创建多行模式空间。模式空间最初的内容和新的输入行之间用换行符分隔。在模式空间中嵌入的换行符可以利用转义序列“\n”来匹配。在多行模式空间中,元字符“^”匹配空间中的第一个字条,而不匹配换行符后面的字符。同样,“$”只匹配模式空间中最后的换行符,而不匹配任何嵌入的换行符。在执行 next命令之后,控制将被传递给脚本中的后续命令。
Next命令与next命令不同,next输出模式空间的内容,然后读取新的输入行。next命令不创建多行模式空间。

示例一:我们假设想要将“0wner and0perator Guide”换成“Installation Guide”,但是我们发现它出现在文件中的两行上,“0perator”和“Guide”被分开了。
[root@localhost ~]# cat z
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.

[root@localhost ~]# sed -r '/Operator$/{N;s/Owner and Operator\nGuide/Installation Guide\n/g}' z
Consult Section 3.1 in the Installation Guide
 for a description of the tape drives
available on your system.
在这个例子中,我们知道行在哪里被拆分成两行,并且知道在哪里指定嵌入的换行符。当这个脚本在样本文件上运行中,它产生两行输出,其中的一行合并了第一行和第二行,在这显示就太长了,发生这种情况的原因是替换命令匹配了嵌入的换行符,但是没有取代它。

示例二:
[root@localhost ~]# cat y
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 including the Owner and
Operator Guide and the User Guide.
The Owner and 0perator Guide is shipped with your system.

[root@localhost ~]# sed 's/Owner and Operator Guide/Installation Guide/;/Owner/{N;s/Owner and Operator\nGuide/Installation Guide\n/;/Owner/{N;s/Owner and\nOperator Guide/Installation Guide\n/}}' y
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 including the Installation Guide
 and the User Guide.
The Owner and 0perator Guide is shipped with your system.
多行删除

删除命令(d)删除模式空间的内容并导致读入新的输入行,从而在脚本的顶端重新使用编辑方法。删除命令(D)稍微有些不同:它删除模式空间中直到第一个嵌入的换行符的这部分内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用于模式空间剩余的内容,我们可以编写一个实现查找一系列空行并输出单个空行的脚本,以看看它们之间的区别。

示例:当遇到一个空行时,下一行就追加到模式空间中。然后试着匹配嵌入的换行符。注意定位元字符~和S分别匹配模式空间的开始处和结束处。
[root@localhost ~]# cat x
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 blank lines.




This is the end.

[root@localhost ~]# sed '/^$/{N;/^\n$/d}' x
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 blank lines.
This is the end.

当有偶数个空行时,所有的空行都会被删除。仅当有奇数个空行时,有一行被保留下来。这是因为删除命令清
除的是整个模式空间。一旦遇到第一个空行,就读入下一行,并且两行都被删除。如果遇到第三个空行,并且
下一行不为空,那么删除命令就不会被执行,因此空行被输出。如果使用多行Delete命令(是D不是d),就能
得到我们想要的结果。

[root@localhost ~]# sed '/^$/{N;/^\n$/D}' x
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 blank lines.

This is the end.

多行Delete命令完成工作的原因是,当遇到两个空行时,Delete命令只删除两个空行中的第一个。下一次遍历该脚本时,这个空行将导致另一行被读入模式空间。如果那行不为空,那么两行都输出,因此确保了输出一个空行。换句话说,当模式空间中有两个空行时、只有第一个空行被删除。当一个空行后面跟有文本时,模式空间可以正常输出。
多行打印

多行打印(Print)命令与小写字母的print命令稍有不同。该命令输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。在执行完脚本的最后一个命令之后,模式空间的内容自动输出(-n选项或#n抑制这个默认的动作)。因此,当默认的输出被抑制或者脚本中的控制流更改,以至不能到达脚本的底部时,需要使用打印命令(P或p) .Print命令经常出现在Next命令之后和Delete命令之前。这3个命令能建立一个输入/输出循环,用来维护两行的模式空间,但是一次只输出一行。这个循环的目的是只输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。创建多行模式空间以匹配第一行结尾处的“UNIX”和第二行开始处的“System”。如果发现“UNIX System”跨越两行,那么我们将它变成“UNIX OperatingSystem”。建立这个循环以返回到脚本的顶端,并寻找第二行结尾处的”UNIX"。

示例:
[root@localhost ~]# cat o
Here are examples of the UNIX
System.Where UNIX
System appears,it should be the UNIX
Operating System.

替换命令匹配“\nSystem”,并且用“Operating\nSystem”取代它。保留换行是很重要的,否则模式空间中就有只一行。注意Print和Delete命令的顺序。

[root@localhost ~]# sed '/UNIX$/{N;/\nSystem/{s// Operating &/;P;D}}' o
Here are examples of the UNIX Operating 
System.Where UNIX Operating 
System appears,it should be the UNIX
Operating System.
输入/输出循环让我们匹配在第二行结束处出现的UNIX。如果正常输出两行的模式空间,那么它就会丢失。
命令缩写功能
Holdh 或 H将模式空间的内容复制或追加到保持空间
Getg 或 G将保持空间的内容复制或追加到模式空间
Exchangex交换保持空间和模式空间的内容

这些命令中的每一条都可以利用一个地址来指定一行或行范围。Hole(h,H)命令将数据移至保持空间、而get(g.G)命令将保持空间的数据移回到模式空间。同一命令的小写字母和大写字母之间的差别是,小字字母命令改写目的缓存区的内容,而大写字母命令追加缓存区的现有内容。

Hold 命令用模式空间的内容取代保持空间的内容。get命令用保持空间的内容取代模式空间的内容。

Hole命令在保持空间的内容之后放置一个换行符,且后面跟随模式空间的内容(即使保持空间是空的,换行符也被追加到保持空间中)。Get命令模式空间的内容之后放置一个换行符,且后面跟随保持空间的内容。

交换命令交换两个缓存区的内容,对两个缓存区没有副作用。

示例:颠倒1和2的顺序
[root@localhost ~]# cat p
1
2
11
22
111
222
这里的目的是颠倒以1开始的行和以2开始的行的顺序。下面展示了如何使用保持空间:我们将第一行复制到保持空间(它一直在那),这时清除模式空间。然后sed 将第二行读入模式空间,并且将保持空间的行追加到模式空间的结尾。
大写G是追加
[root@localhost ~]# sed '/1/{h;d};/2/{G}' p
2
1
22
11
222
111
如果用小写g的话2会被覆盖只剩下1
[root@localhost ~]# sed '/1/{h;d};/2/{g}' p
1
11
111

x:交换
[root@localhost ~]# sed -n '/2/{h;x;p}' p
2
22
222
先匹配2然后用覆盖的方式放在中间然后打印出来
大写转换

转换命令(y),在一行上能将小写字母转换为大写字母。因为y命令作用于模式空间的所有内容,所以对行的一部分进行逐字转换有点繁琐。

转换命令可以进行小写字母到大写字母的转换,但它将转换应用于整个行。使用保持空间可以实现以上任务,因为可以用保持空间来存储输入行的备份而将语句名独立出来,并在模式空间进行转换。

[root@localhost ~]# cat h
find the Match statement
Consult the Get statement.
Using the Read statement to retrieve data
[root@localhost ~]# sed -r '/the .* statement/{h;s/.*the (.*) statement.*/\1/;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/(.*)\n(.*the ).*( statement.*)/\2\1\3/}' h
find the MATCH statement
Consult the GET statement.
Using the READ statement to retrieve data
  • 32
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值