文本处理之sed
文本处理三剑客:
sed
awk
grep
sed基本语法
//[address]command
[root@localhost ~]# cat anaconda-ks.cfg
#version=RHEL8
# Use graphical install
graphical //删掉这一行
repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream
%packages
@^minimal-environment
@development
kexec-tools
[root@localhost ~]# sed '/^graphical/d' anaconda-ks.cfg //匹配删除
#version=RHEL8
# Use graphical install
//[line-address]command
[root@localhost ~]# cat anaconda-ks.cfg -n //-n显示行号
1 #version=RHEL8
2 # Use graphical install
3 graphical
4 repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream
5 %packages
6 @^minimal-environment
7 @development
[root@localhost ~]# sed '3d' anaconda-ks.cfg //删除选择的行
#version=RHEL8
# Use graphical install
//对一个文本进入多个命令修改可以用大括号进行分组以使其作用与同一个地址
address{
command1
command2
command3
}
替换
我们已经讨论了替换命令的许多用法。下面是它的详细的用法:
[address]s/pattern/replacement/flags
这里修饰替换的标志flags 是:
n 1到512之间的一个数字,表示对文本模式中指定模式第n次出现的情况进行替换
g 对模式空间的所有出现的情况进行全局更改。而没有g是通常只有第一次出现的情况被取代。
p 打印模式空间的内容。
w file 将模式空间的内容写到文件file 中。
和地址不同的是,地址需要一个作为定界符的斜杠(/) ,而正则表达式可以用任意字符来分隔,只有换行符除外。因此,如果模式包含斜杠,那么可以选择另一-个字符作为定界符,例如感叹号。
s !/usr/mail!/usr2/mail !
注意,定界符出现了3次而且在replacement之后是必需的。不管使用哪种定界符,如果它出现在正则表达式中,或者在替换文本中,那么就用反斜杠来转义它。
[root@localhost ~]# echo '/usr/local/src' | sed 's/\/usr\/local\/src/\/user\/local\/src/'
/user/local/src
[root@localhost ~]# echo '/usr/local/src' | sed 's#/usr/local/src#/user/local/src#'
/user/local/src
[root@localhost ~]# echo '/usr/local/src' | sed 's!/usr/local/src!/user/local/src!'
/user/local/src
Replacement是一个字符串,用来替换与正则表达式匹配的内容。在replacement部分,只用下列字符有特殊含义:
& 用正则表达式匹配的内容进行替换。
\n 匹配第n个字串(n是一个数字),这个字串以前在pattern 中用““和““和““指定。
\ 当在替换部分包含“与“符号(&),反斜杠(\)和替换命令的定界符时可用\转义它们。另 外,它用于转义换行符并创建多行replacement字符串。
数字表示很少使用,在这种情况下,正则表达式在一行上重复匹配,而只需要对其中某个位置的匹配进行替换。例如,某输入行也许包含tb1输入,也许包含多个制表位。假设每行有3个制表符,并且要用“>“替换第二个制表位,则可以使用下面的替换命令完成该功能:
s /·/>/2
“·”表示一个真正的制表符,而制表符在屏幕上是不可见的。如果输入是一行的文件,如下所示:
Column1·Col umn2·Column3·Col umn4
[root@localhost ~]# touch 123
[root@localhost ~]# vim 123
[root@localhost ~]# cat 123
Column1 Column2 Column3 Column4
[root@localhost ~]# sed 's/\t/>/2' 123
Column1 Column2>Column3 Column4
替换元字符
替换元字符是反斜杠(\)、“与”符号(&)和\n。反斜杠一般用于转义其他的元字符,但是他在替换字符串中也用于包含换行符。
例1
[root@localhost ~]# echo '.Ah "Major Heading"' > 123
[root@localhost ~]# cat 123
.Ah "Major Heading"
[root@localhost ~]# sed '/^\.Ah/{
> s/\.Ah */\
> \
> @A HEAD = /
> s/"//g
> s/$/\
> /
> }' 1
@A HEAD = Major Heading
[root@localhost ~]# sed '/^\.Ah/{s/\.Ah */\n@A HEAD = /;s/"//g};s/$/\n/' 123
@A HEAD = Major Heading
//拆开分步操作
[root@localhost ~]# cat a
.Ah "Major Heading"
ORA Associates, Inc.
[root@localhost ~]# sed -r "s/ORA (.*)/O'Reilly &/g" a
.Ah "Major Heading"
O'Reilly ORA Associates, Inc.
[root@localhost ~]# sed 's/ORA.*/& 123/g' a
.Ah "Major Heading"
ORA Associates, Inc. 123
例二
[root@localhost ~]# cat 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
[root@localhost ~]# sed 's/UNIX/\\s-2&\\s0/g' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the \s-2UNIX\s0 Operating System.
删除
重要的是:如果某行匹配这个地址,那么就删除整个行,而不只是删除行中匹配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)。删除空行的命令:
/^$/d
[root@localhost ~]# cat test
123
456
789
[root@localhost ~]# sed '/^$/d' test //删除空行
123
456
789
[root@localhost ~]# cat 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
[root@localhost ~]# sed '/^\.Ah/d' 1 //删除.Ah开头的
ORA Associates, Inc.
on the UNIX Operating System.
追加、插入和更改
追加(a)、插入(i)和更改(c)命令提供了通常在交互式编辑器(例如vi)中所选的编辑功能。你会奇怪地发现、可以使用这些相同的命令在非交互编辑器中“输入”文本。这些命令的语法在sed中不常用,因为它们必须在多行上来指定。语法如下:
*追加[line-address]a*
text
*插入[line-address] i *
text
*更改[address]c*
text
插入命令将所提供的文本放置在模式空间的当前行之前。追加命令将文本放置在当前行之后。更改命令用所提供的文本取代模式空间的内容。
//追加abc
[root@localhost ~]# sed '1 a abc' 1
.Ah "Major Heading"
abc
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost ~]# sed '1 a \ abc' 1
.Ah "Major Heading"
abc
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
//插入abc
[root@localhost ~]# sed '/^\.Ah/iabc' 1 //在第一行插入abc
abc
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
//更改
[root@localhost ~]# cat 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost ~]# sed '/^\.Ah/,/on /cabc' 1 //从.Ah开头到on这一行更改为abc
abc
See Section 1.4
See Section 12.9
first:second
one:two
转换
转换命令是特有的,不仅因为它在所有的sed命令中拥有最小的肋记符。这个命令按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符。
它的语法如下:
[address]y/abc/xyz/
[root@localhost ~]# cat 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost ~]# sed '1y/Helding/123/' 1
.Ah "Major 123"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
打印
打印命令(p)输出模式空间的内容。它既不清除模式空间也不改变脚本中的控制流。然而,它频繁地用在改变流控制的命令(d,N, b)之前。
除非抑制(-n)默认的输出,否则打印命令将输出行的重复复制。当抑制默认的输出或者当通过程序的流控制来避免到达脚本的底部时,可能会使用它。
[root@localhost ~]# cat 1
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"
[root@localhost ~]# sed '/^\.Ah/{p;s/"//g;s/^\.Ah //}' 1
.Ah "Comment"
Comment
.Ah "Substitution"
Substitution
.Ah "Delete"
Delete
.Ah "Append, Insert and Change"
Append, Insert and Change
.Ah "List"
List
打印行号
跟在地址后面的等号(=)打印被匹配的行的行号。除非抑制行的自动输出,行号和行本身将被打印。它的语法如下:
[line-address]=
[root@localhost ~]# cat 1
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"
[root@localhost ~]# sed -n '/Comment/{=;p}' 1 //打印行号
1
.Ah "Comment"