基本sed命令

基本sed命令

1. 替换

语法格式

[address]s/pattern/replacement/flags

修饰替换的标志flag是:

  • n 1到512之间的一个数字,表示对文本模式中指定模式第n次出现的情况进行替换
  • g 对模式空间的所有出现的情况进行全局更改。而没有g是通常只有第一次出现的情况被取代。
  • p 打印模式空间的内容。
  • w file 将模式空间的内容写到文件file 中。

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

和地址不同的是,地址需要一个作为定界符的斜杠(/),而正则表达式可以用任意字符来分隔,只有换行符除外。因此,如果模式包含斜杠,那么可以选择另一个字符作为定界符,例如感叹号。

s !/usr/mail !/usr2/mail !

注意,定界符出现了3次而且在replacement之后是必需的。不管使用哪种定界符,如果它出现在正则表达式中,或者在替换文本中,那么就用反斜杠来转义它。

因为在内部存储时换行符只是一个字符,所以正则表达式可以使用“\n”来匹配嵌入的换行符。

Replacement是一个字符串,用来替换与正则表达式匹配的内容(参见第三章中的“匹配的范围“一节)。在replacement部分,只用下列字符有特殊含义:

  • & 用正则表达式匹配的内容进行替换。
  • \n 匹配第n个字串(n是一个数字),这个字串以前在pattern 中用“v(“和“)“指定。
  • \ 当在替换部分包含“与“符号(&),反斜杠()和替换命令的定界符时可用\转义它们。另外,它用于转义换行符并创建多行replacement字符串。

Flag可以组合使用,只要有意义。例如,gp表示对行进行全局替换并打印这一行。迄今为止,全局标志是最常用的。没有它,替换只能在行的第一次出现的位置执行。

示例:

#编辑一个文件,作为演示对象
[root@localhost ~]# echo 'Alice Ford, 22 East Broadway, Richmond VA ' > abc
[root@localhost ~]# cat abc 
Alice Ford, 22 East Broadway, Richmond VA 

#使用&匹配,替换成223,其中&表示22
[root@localhost ~]# sed 's/22/&3/' abc 
Alice Ford, 223 East Broadway, Richmond VA

#替换成22 3
[root@localhost ~]# sed 's/22/& 3/' abc 
Alice Ford, 22 3 East Broadway, Richmond VA 

#替换成322,把3写在&前面就行了
[root@localhost ~]# sed 's/22/3&/' abc 
Alice Ford, 322 East Broadway, Richmond VA 

#使用正则表达式的表示,数字是0-9位数是2位数,在后面加上3
[root@localhost ~]# sed -r 's/[0-9]{2}/&3/' abc 
Alice Ford, 223 East Broadway, Richmond VA

2. 替换元字符

替换元字符是反斜杠()、“与”符号(&)和\n。反斜杠一般用于转义其他的元字符,但是他在替换字符串中也用于包含换行符。

来自于将troff文件转换成Ventura Publisher的 ASCIl输入格式,它将下面的troff行:

.ah "Major Heading"

转换成类似的Ventura Publisher行:

@A HEAD = Major Heading

这个问题中的难点是这一行需要前后都有空行,这是一个编写多行替换字符串的问题。

#编辑一个test文件,用于演示
[root@localhost ~]# echo '.Ah "Major Heading"' > test
[root@localhost ~]# cat test 
.Ah "Major Heading"

#多行替换字符串
[root@localhost ~]# sed '
/^\.Ah */{
s/\.Ah */\
\
@A HEAD = /
s/"//g
s/$/\
/    
}' test


@A HEAD = Major Heading

#

第一个替换命令用两个换行符和“@A HEAD =”取代“.Ah”,在行结尾处有必要用反斜杠转义换行符。第二个替换删除了引号。最后一个命令匹配模式空间中的行的结尾(不是嵌入的换行符),并在它后面添加一个换行符。

当正则表达式匹配单词的变化时,“与”符号特别有用。它允许指定一个可变的替换字符串,该字符串相当于匹配的内容与实际内容匹配的字符创。例如,假设要用圆括号括住文档中对已编号部分的任意交叉引用。换句话说,任意诸如“See Section 1.4”或“See Section 12.9”的引用都应该出现在圆括号中,如“(See Section 12.9)”。正则表达式可以匹配数字的不同组合,所以在替换字符串中可以使用“&”并括起所匹配的内容。

#示例文件
[root@localhost ~]# cat file1 
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#匹配1.1在1.1的一行前面追加123
[root@localhost ~]# sed '/1\.1/i\123' file1 
123
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#删除整数部分为1-9,小数点后面部分为2位数的一行
[root@localhost ~]# sed -r '/See Section [1-9]\.[1-9][0-9]*/d' file1 
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999

#&符号用于在替换字符串中引用整个匹配内容
[root@localhost ~]# sed 's/See Section [1-9][0-9]*\.[1-9][0-9]*/(&)/' file1 
(See Section 1.1)
(See Section 99.99)
(See Section 50.1)
(See Section 999.99)
(See Section 99.999)
(See Section 5.19)

#当节号出现在交叉引用中时要表示用粗体,可以编写下面的替换
[root@localhost ~]# sed -r 's/(See Section) ([1-9][0-9]*\.[1-9][0-9]*)/\1 \\fB\2\\fP/' file1 
See Section \fB1.1\fP
See Section \fB99.99\fP
See Section \fB50.1\fP
See Section \fB999.99\fP
See Section \fB99.999\fP
See Section \fB5.19\fP

3. 删除

它还可以删除文件中的特定行,它能够从文件中删除表达式,文件可以通过指定分隔符(例如逗号、制表符或空格)进行标识。

删除命令对照表

查询命令 含义
1d 删除第1行内容
1,10d 删除1行到10行的内容
1,+5d 删除1行到6行的内容
/pattern1/d 删除每行中匹配到pattern1的行内容
/pattern1/,/pattern2/d 删除匹配到pattern1的行直到匹配到pattern2的所有行内容
/pattern1/,10d 删除匹配到pattern1的行到10行的所有行内容
10,/pattern1/d 删除第10行直到匹配到pattern1的所有行内容

示例:

#示例文件
[root@localhost ~]# cat file1 
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#匹配See Section 删除整数位为一位数,小数为为两位数的行
[root@localhost ~]# sed -r '/See Section [1-9]\.[0-9]{1,2}/d' file1 
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999

4. 追加丶插入和更改

追加(a)、插入(i)和更改(c)命令提供了通常在交互式编辑器(例如vi))中所选的编辑功能。你会奇怪地发现、可以使用这些相同的命令在非交互编辑器中“输入”文本。这些命令的语法在sed中不常用,因为它们必须在多行上来指定。语法如下:

追加[line-address]a\
text
插入[line-address] i \
text
更改[address]c\
text

插入命令将所提供的文本放置在模式空间的当前行之前。追加命令将文本放置在当前行之后。更改命令用所提供的文本取代模式空间的内容。

这些命令中的每一个都要求后面跟一个反斜杠用于转义第一个行尾。text必须从下一行开始。要输入多行文本,每个连续的行都必须用反斜杠结束,最后一行例外。

示例:

#示例文件
[root@localhost ~]# cat file1 
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

//追加 a
#在第一行追加2
[root@localhost ~]# sed '1a2' file1 
See Section 1.1
2
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#使用匹配1.1的方式追加
[root@localhost ~]# sed '/1.1/ahehe' file1 
See Section 1.1
hehe
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

//插入 i
#在第一行插入hehe
[root@localhost ~]# sed '1ihehe' file1 
hehe
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#匹配50.1插入123换行456
[root@localhost ~]# sed '/50\.1/i\
123\
456' file1
See Section 1.1
See Section 99.99
123
456
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

//修改 c
#第一行修改为hehe
[root@localhost ~]# sed '1chehe' file1 
hehe
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#匹配H开头这一行到空行,修改为hehe
[root@localhost ~]# cat test 
Here are the books that you requested
Yes, it is a good book for children

It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe
[root@localhost ~]# sed '/^H/,/^$/chehe' test 
hehe
It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe

#第一行修改为See Section hehe
[root@localhost ~]# sed '1cSee Section hehe' file1 
See Section hehe
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

5. 转换

转换命令y是sed特有的,不仅因为它在所有的sed命令中拥有最小的助记符。这个命令按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符,它的语法如下:

[address]y/abc/xyz/

示例:

#示例文件
[root@localhost ~]# cat test 
Here are the books that you requested
Yes, it is a good book for children

It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe

#把are对应转换成123
[root@localhost ~]# sed 'y/are/123/' test 
H323 123 th3 books th1t you 23qu3st3d
Y3s, it is 1 good book fo2 child23n

It is 1mzing to think th1t it w1s c1ll3d 1 "h12mful book" wh3nonc3 you g3t to th3 3nd of th3 book,you c1n't b3li3v3

6. 打印

打印命令(p)输出模式空间的内容。它既不清除模式空间也不改变脚本中的控制流。然而,它频繁地用在改变流控制的命令(d,N,b)之前。除非抑制(-n)默认的输出,否则打印命令将输出行的重复复制。当抑制默认的输出或者当通过程序的流控制来避免到达脚本的底部时,可能会使用它。

示例:

 [root@localhost ~]# cat file1 
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#因为sed默认就会打印一次
[root@localhost ~]# sed '/[1-9][0-9]*\.[1-9][0-9]*/{
> =
> p
> }' file1
1
See Section 1.1
See Section 1.1
2
See Section 99.99
See Section 99.99
3
See Section 50.1
See Section 50.1
4
See Section 999.99
See Section 999.99
5
See Section 99.999
See Section 99.999
6
See Section 5.19
See Section 5.19

#加上-n就会打印一次了
[root@localhost ~]# sed -n '/[1-9][0-9]*\.[1-9][0-9]*/{
=
p
}' file1
1
See Section 1.1
2
See Section 99.99
3
See Section 50.1
4
See Section 999.99
5
See Section 99.999
6
See Section 5.19

7. 下一步

下一步(next)命令(n)输出模式空间的内容,然后读取输入的下一行,而不用返回到脚本的顶端。它的语法如下:

[address]n

示例:

#示例文件
[root@localhost ~]# cat test 
Here are the books that you requested
Yes, it is a good book for children

It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe
#匹配Yes下一行删除
[root@localhost ~]# sed '/Yes/{
> n
> d
> }' test
Here are the books that you requested
Yes, it is a good book for children
It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe

8. 读和写入文件

读(r)和写(w)命令用于直接处理文件。这两个命令都只有一个参数,即文件名。语法如下:

[line-address]r file[address]w file

示例:

#示例文件
[root@localhost ~]# cat test 
Here are the books that you requested
Yes, it is a good book for children

It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe

[root@localhost ~]# cat file1 
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19
#在test文件中匹配Yes这一行,在后面读取file1文件
[root@localhost ~]# sed '/Yes/rfile1' test 
Here are the books that you requested
Yes, it is a good book for children
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

It is amzing to think that it was called a "harmful book" whenonce you get to the end of the book,you can't believe

9. 退出

退出命令(q)会使sed停止读取新的输入行(并停止将它们发送到输出)。它的语法为:

[line-address]q

示例:

#示例
[root@localhost ~]# cat file1 
See Section 1.1
See Section 99.99
See Section 50.1
See Section 999.99
See Section 99.999
See Section 5.19

#退出
[root@localhost ~]# sed '1q' file1 
See Section 1.1
[root@localhost ~]# sed '2q' file1 
See Section 1.1
See Section 99.99
[root@localhost ~]# sed '3q' file1 
See Section 1.1
See Section 99.99
See Section 50.1
posted @ 2021-03-29 23:48  我爱吃芹菜~  阅读(265)  评论(0编辑  收藏  举报
Title