文本处理三剑客之sed

发布于:2022-08-02 ⋅ 阅读:(211) ⋅ 点赞:(0)

文本处理三剑客:

  •         sed
  •         awk
  •         grep

 

基本sed命令

sed命令的语法

语法格式:[address]command
[root@localhost ~]# cat anaconda-ks.cfg 
#version=RHEL8
# Use graphical install
graphical
[root@localhost ~]# sed '/^graphical/d' anaconda-ks.cfg 
#version=RHEL8
# Use graphical install

语法格式(标识行的范围):[line-address]command
[root@localhost ~]# cat anaconda-ks.cfg -n
     1	#version=RHEL8
     2	# Use graphical install
     3	graphical
[root@localhost ~]# sed '3d' anaconda-ks.cfg 
#version=RHEL8
# Use graphical install

大括号进行分组使其作用于一个地址
address{
command1
command2
command3
}

替换

我们已经讨论了替换命令的许多用法。下面是它的详细的用法:

[address]s/pattern/replacement/flags

这里修饰替换的标志flags 是:

    1到512之间的一个数字,表示对文本模式中指定模式第n次出现的情况进行替换

     对模式空间的所有出现的情况进行全局更改。而没有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 ~]# cat abc
Column1	Column2	Column3	Column4
[root@localhost ~]# sed 's/\t/>/2' abc
Column1	Column2>Column3	Column4     //替换后的结果显示

替换元字符

替换元字符是反斜杠(\)、“与”符号(&)和\n。反斜杠一般用于转义其他的元字符,但是他在替换字符串中也用于包含换行符。
我们可以对前面的示例做一些改动,用换行符取代每行上的第二个制表符。
s/·/\
 /2

//第一个例子
[root@localhost ~]# sed 's/\t/\n/2' abc
Column1	Column2
Column3	Column4
产生的结果
//第二个例子
[root@localhost ~]# echo '.Ah "Major Heading"' > 1
[root@localhost ~]# cat 1
.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/' 1

@A HEAD = Major Heading
//第三个例子
[root@localhost ~]# cat 1
.Ah "Major Heading"
ORA Associates, Inc.
[root@localhost ~]# sed -r "s/ORA (.*)/O'Reilly &/g" 1
.Ah "Major Heading"
O'Reilly ORA Associates, Inc.

[root@localhost ~]# sed 's/ORA.*/& 123/g' 1
.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.
//第五个例子
[root@localhost ~]# cat 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
[root@localhost ~]# sed 's/See Section [1-9][0-9]*\.[1-9][0-9]*/(&)/g' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
(See Section 1.4)
(See Section 12.9)
[root@localhost ~]# sed -r 's/(.*) ([1-9][0-9]*\.[1-9][0-9]*)/\1\\fB\2\\fP/g' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section\fB1.4\fP
See Section\fB12.9\fP

[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 -r 's/(.*):(.*)/\2:\1/g' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
second:first
two:one

d删除

重要的是:如果某行匹配这个地址,那么就删除整个行,而不只是删除行中匹配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)。上一章展示了删除空行的命令:
/^$/d

[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/d' 1   //删除.Ah开头的
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two

追加、插入和更改

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

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


这些命令中的每一个都要求后面跟一个反斜杠用于转义第一个行尾。text必须从下一行开始。要输入多行文本,每个连续的行都必须用反斜杠结束,最后一行例外。例如,下面的插入命令在匹配“<Larry' s Address>”行的地方插入两行文本:
/<Larry' s Address>/i\

4700 Cross Court\
French Lick,IN

而且,如果文本包含一个字面的反斜杠,要再添加一个反斜杠来转义它
 

#追加a
[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 '1 a abc' 1    //在第一行后面加abc
.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
[root@localhost ~]# sed '/^\.Ah/a \  hehe' 1
.Ah "Major Heading"
  hehe
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost ~]# sed '/^See/a 123' 1
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
123
See Section 12.9
123
first:second
one:two


#插入i
[root@localhost ~]# sed '/^\.Ah/iabc' 1
abc
.Ah "Major Heading"
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two


#更改c
[root@localhost ~]# sed '1 c hehe' 1   //改变第一行
hehe
ORA Associates, Inc.
on the UNIX Operating System.
See Section 1.4
See Section 12.9
first:second
one:two
[root@localhost ~]# sed '/ORA/c \  hh' 1
.Ah "Major Heading"
  hh
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
[root@localhost ~]# sed '/^\.Ah/,$cabc' 1   //全部都改了
abc

转换

转换命令是特有的,不仅因为它在所有的sed命令中拥有最小的肋记符。这个命令按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符(注9)。它的语法如下:
[address]y/abc/xyz/
注9这个命令在UNIX tr命令之后被模式化,被用于转换字符。这本身是一
个非常有用的命令,参阅你的本地文档的详细资料。无疑、如果t还没有被使用 ,那么sed 的y命令就应该命名为t。
替换根据字符的位置来进行。因此,它没有“词”的概念。这样,在该行上的任何地方的“a”都被换成了“x”,而不管它后面是否跟有“b”。这个命令的一个可能的用处是用大写字母替换对应的小写字母,
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
这个命令影响整个模式空间的所有内容。如果想在输入行上转换单个单词,那么通过使用保持空间可以完成。参见有关如何使用保持空间的介绍(大致过程是:输出更改单的那一行之前的所有行,删除这些行,将单词后面的行复制到保持空间,转换这个单词,然后将保持空间的内容追加到模式空间)。
 

[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/ajo/123/' 1
.Ah "M123r He1ding"
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 2
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"
[root@localhost ~]# sed '/^\.Ah/{p;s/"//g;s/^\.Ah //}' 2
.Ah "Comment"
Comment
.Ah "Substitution"
Substitution
.Ah "Delete"
Delete
.Ah "Append, Insert and Change"
Append, Insert and Change
.Ah "List"
List

打印行号

跟在地址后面的等号(=)打印被匹配的行的行号。除非抑制行的自动输出,行号和行本身将被打印。它的语法如下:
[line-address]=
这个命令不能对一个范围内的行进行操作。
程序员也许用该命令打印源文件中的某些行。例如,下面的脚本打印行号和行本身,这些行都包含后面跟有字符串“if”的制表符。脚本如下:
#n打印具有if语句的行号和行
/    if/{
=
p

}

[root@localhost ~]# cat 2
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"
[root@localhost ~]# sed -n '/Comment/{=;p}' 2     //打印出Comment行号
1
.Ah "Comment"

下一步

下一步(next)命令(n)输出模式空间的内容,然后读取输入的下一行,而不用返回到脚本的顶端。它的语法如下:
[address]n
next命令改变了正常的流控制,直到到达脚本的底部才会输出模式空间的内容,它总是在读入新行之后从脚本的顶端开始。实际上,next命令导致输入的下-一行取代横穿空间中的当前行。脚本中的后续命令应用于替换后的行,而不是当前行。如果没有抑制默认输出,那么在替换发生之前会打印当前行。

[root@localhost ~]# cat 2
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"
[root@localhost ~]# sed -n '/Comment/p' 2
.Ah "Comment"
[root@localhost ~]# sed -n '/Comment/n;p' 2    //打印Comment下一行的东西
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"


[root@localhost ~]# cat 2
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Comment"
.Ah "Append, Insert and Change"
.Ah "Comment"
.Ah "List"
[root@localhost ~]# sed -r '/Comment/{n;s/\.Ah (.*)/\.Ah (\1)/g}' 2
.Ah "Comment"
.Ah ("Substitution")
.Ah "Delete"
.Ah "Comment"
.Ah ("Append, Insert and Change")
.Ah "Comment"
.Ah ("List")
//在Comment下一行的加括号
//删除其中的空行
[root@localhost ~]# cat 2
.Ah "Comment"

.Ah "Substitution"
.Ah "Delete"
.Ah "Comment"

.Ah "Append, Insert and Change"
.Ah "Comment"
.Ah "List"
[root@localhost ~]# sed '/Comment/{n;/^$/d}' 2
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Comment"
.Ah "Append, Insert and Change"
.Ah "Comment"
.Ah "List"

读和写文件

读(r)和写(w)命令用于直接处理文件。这两个命令都只有一个参数,即文件名。语法如下:
[line-address]r file[address]w file
读命令将由file指定的文件确定的行之后的内容读入模式空间。它不能对一个范围内的行进行操作。写命令将模式空间的内容写到file 中。
在命令和文件名之前必须有一个空格(空格后到换行符前的每个字符都被当做文件名.因此,前导的和嵌入的空格也是文件名的一部分)。如果文件不存在,读命令也不会报错。如果写命令中指定的文件不存在,将创建一个文件;如果文件已经存在,那么写命令将在每次调用脚本时改写它。如果一个脚本中有多个指令写到同一个文件中,那么每个写命令都将内容追加到这个文件中。而且,每个脚本最多只能打开10个文件。
 

[root@localhost ~]# cat 2
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Comment"
.Ah "Append, Insert and Change"
.Ah "Comment"
.Ah "List"
[root@localhost ~]# sed '/Comment/{n;/^$/d};w 4' 2   //把Comment下一行的内容写入4这个文件
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Comment"
.Ah "Append, Insert and Change"
.Ah "Comment"
.Ah "List"
[root@localhost ~]# cat 4
.Ah "Substitution"
.Ah "Delete"
.Ah "Append, Insert and Change"
.Ah "List"


网站公告

今日签到

点亮在社区的每一天
去签到