sed与awk命令

2022/9/16 6:17:25

本文主要是介绍sed与awk命令,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 1 基本sed命令
    • 1.1 sed命令语法
    • 1.2 注释
    • 1.3 替换
    • 1.4 删除
    • 1.5 追加、插入和更换
    • 1.6 列表
    • 1.7 转换
    • 1.8 打印
    • 1.9打印行号
    • 1.10下一步
  • 2. 高级sed命令
    • 2.1 多行模式空间
    • 2.2 追加下一行
    • 2.3 多行删除
    • 2.4 多行打印
    • 2.5 包含那一行
    • 2.6 大写转换

1 基本sed命令

1.1 sed命令语法

在看单个命令以前,需要回顾一下关于所有sed命令的两点语法。在上一个章
中,我们介绍了其大部分内容。
行地址对于任何命令都是可选的。它可以使一个模式,被描述为由斜杠、行号
或行寻址符号括住的正则表达式。大多数sed命令能接受由逗号分隔的两个地
址,这两个地址,这两个地址用来标识行的范围。这些命令的语法格式为:
[address] commnand
有一些命令只接受单个行地址。它们不能应用于某个范围的行。它们的语法格.
式为:
[line- -address] command
记住命令还可以用大括号进行分组以使其作用于同一个地址:
ac
addr
ess
s{
command1
command2
command3
}
第一个命令可以喝左大括号放置在同一行,但是右大括号必须自己单独处于一
行。每个命令都可以有自己的地址并允许有多层分组。而且,就像命令在大括
号内的缩进方式一样,允许在行的开始处插入空格和制表符。
当sed 不理解一一个命令时,它打印出消息“Command garbled(命令 不清)”。在
命令后添加空格会产生一个小的语法错误,这个不允许的,命令的结束必须在
行的结尾处。
这个约束的依据是来自一个文档中“无记载”特征提供的:如果命令之间用一
个分号分隔,那么可以将多个sed命令放在同一行(注1)。下面的示例在语:
句构成上是正确的:
n;d
然而,在n命令后面放置一个空格会导致语法错误,而在d命令前面放置一个
空格是可以的。
不提倡在同一行放置多个命令,因为即使将这些命令写在各自的行上,sed 脚.
本也是很难阅读的(注意,更改、插入和追加命令必须在多行.上指定,不能在
同一行.上指定)。

1.2 注释

可以使用注释描述脚本的作用,来为脚本编写文档。从本章开始,完整的脚本
示例都以一个注释行开始。注释行可以作为脚本的第一行出现。在sed的
System V版本中,注释只允许出现在第一行。在一些版本中,包括SunOS 4. 1x
环境下运行的sed以及GNU sed,可以在脚本的任何地方放置注释,甚至是跟
在命令行的后面。本书的示例更多地遵循System V sed的限制,将注释限制在
脚本的第一行。然而,使用注释作为脚本文档往往非常有效,如果你的sed版
本允许则应该使用它。
注释1:
令人惊讶的是,用分号分隔命令的用法不在POSIX标准中。
注释行的第一个字必须是“#”号。注释行的语法如下:
#[n] 下列显示了一个脚本的第一行: #wstar. sed: convert WordStar files .
如果有必要,可以用反斜杠来结束前面的行使得注释可以继续多行(注释
2)。为了前后一致,必须用#开始继续行,以便使行的目的显而易见。
如果跟在#后面的下一个字符是n,那么脚本不会自动产生输出。这和指令命令
行选项-n是等价的。跟在n后面的其余的内容被看做是注释。在POSIX标准.
中,采用这种方式的#n必须是文件的前两个字符。

1.3 替换

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

[root@localhost ~]# cat 123
.Ah "Major Heading"
[root@localhost ~]# sed '/^\.Ah/{s/\.Ah*/@A HEAD =/g}' 123
@A HEAD = "Major Heading"
[root@localhost ~]# sed '/^\.Ah/{s/\.Ah*/@A HEAD =/g;s/"//g}' 123
@A HEAD = Major Heading

或者

[root@localhost ~]# sed '
> /^\.Ah/{
> s/\.Ah*/\
> \
> @A HEAD =/
> s/"//g
> }' 123


@A HEAD = Major Heading

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

[root@localhost ~]# cat 123
See Section 1.4
See Section 12.9
[root@localhost ~]# sed 's/See Section [1-9][0-9]*\.[1-9] [0-9]*/ (&)/' 123
(See Section 1.4)
(See Section 12.9)

1.4 删除

前面已经展示了删除命令(d)的示例。它采用一个地址,如果行匹配这个地址
就删除模式空间的内容。
删除命令还是一个可以改变脚本中的控制流的命令。这是因为一旦执行这个命
令,那么在“空的”模式空间(注4)中就不会再有命令执行。删除命令会导
致读取新输入行,而编辑脚本则从头开始新的一轮(这一行为和ne
xt命令的行
为相同,本章后面将介绍next命令)。
重要的是:如果某行匹配这个地址,那么就删除整个行,而不只是删除行中匹
配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)。上
一章展示了删除空行的命令:
/^$/d
删除命令的另一个用处是去除某些troff请求、例如

意义
/^. sp/d 添加空格
/^. bp/d 分页
. /^. nf/d 填充模式的打开
/^. fi/d 填充模式的关闭
这些命令删除一个完整的行。例如,第一个命令删除行“.sp 1”或
sp.03v"
删除命令可以用于删除一个范围内的行。在上一章中,有一个通过删除宏. TS
和. TE之间的行来删除文件中的所有表格的示例。还有一个删除命令(D) 用于
删除多行模式空间的一部分。

1.5 追加、插入和更换

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

追加

[root@localhost ~]# cat 123
See Section 1.4
See Section 12.9
[root@localhost ~]# sed '/1.4/ajjyy' 123
See Section 1.4
jjyy
See Section 12.9

插入

[root@localhost ~]# cat 123
See Section 1.4
jjyy
See Section 12.9
[root@localhost ~]# sed '2i123' 123
See Section 1.4
123
jjyy
See Section 12.9

更改

[root@localhost ~]# cat 123
See Section 1.4
jjyy
See Section 12.9
[root@localhost ~]# sed '2chello world' 123
See Section 1.4
hello world
See Section 12.9

1.6 列表

列表命令(I)用于显示模式空间的内容,将非打印的字符显示为两个数字的
ASCII代码。其功能类似于vi中的列表命令(:1) 。可以使用该命令来检测输
入中的“不可见”字符(注6)
$ cat test/ spchar
Here is a string of special characters:^ A^ B^M ^G
$sed-n-e
"I”test/ spchar
Here is a string of special characters: \01 \02\15 \07
$ #test with GNU sed too
$ gsed -n -e "I”test/ spchar
Here is a string of special characters:\01 \02\r \a

1.7 转换

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

[root@localhost ~]# cat 123
See Section 1.4
123
jjyy
See Section 12.9
[root@localhost ~]# sed 'y/1/a/' 123
See Section a.4
a23
jjyy
See Section a2.9
[root@localhost ~]# sed 's/1/a/' 123
See Section a.4
a23
jjyy
See Section a2.9
[root@localhost ~]# cat 123
See Section 1.4
123
jjyy
See Section 12.9
[root@localhost ~]# sed 's/e/a/' 123
Sae Section 1.4
123
jjyy
Sae Section 12.9
[root@localhost ~]# sed 'y/e/a/' 123
Saa Saction 1.4
123
jjyy
Saa Saction 12.9
[root@localhost ~]# 

1.8 打印

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

[root@localhost ~]# cat 123
See Section 1.4
123
jjyy
See Section 12.9
[root@localhost ~]# sed 'p' 123
See Section 1.4
See Section 1.4
123
123
jjyy
jjyy
See Section 12.9
See Section 12.9
[root@localhost ~]# sed -n '3p' 123
jjyy

1.9打印行号

跟在地址后面的等号(=)打印被匹配的行的行号。除非抑制行的自动输出,行
号和行本身将被打印。它的语法如下:
[line-address]=

[root@localhost ~]# cat 123
See Section 1.4
123
jjyy
See Section 12.9
[root@localhost ~]# sed '=' 123
1
See Section 1.4
2
123
3
jjyy
4
See Section 12.9

1.10下一步

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

[root@localhost ~]# cat 123
See Section 1.4
123
jjyy
See Section 12.9
[root@localhost ~]# sed -n '2n;p' 123
See Section 1.4
jjyy
See Section 12.9
[root@localhost ~]# sed '2n' 123
See Section 1.4
123
jjyy
See Section 12.9

[root@localhost ~]# cat 123
.H1 "0n Egypt'

Napoleon, pointing to the Pyramids, said to his troops:
"Soldiers,forty centur ies have their eyes upon you.
[root@localhost ~]# sed '/^\.H1/{n;p}' 123
.H1 "0n Egypt'


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

2. 高级sed命令

2.1 多行模式空间

在前面正则表达式的讨论中,我们强调模式匹配是面向行的。像grep这样的程
序尝试在单个输入行上匹配一个模式。这就使它很难匹配一个在一行的结尾处
开始。并在下一行的开始处结束的短语。其他一-些模式只有当在多行.上重复时才有意义。
sed能查看模式空间的多个行。这就是允许匹配模式扩展到多行上。在本节
中,我们将来看一下创建多行模式空间并处理它的内容的命令。这里的3个多
行命令(N、D、P)对应于上一章出现的小写字母的基本命令(n、d、p)。例
如,删除命令(D)是删除命令(d)的多行形式。区别是:d删除模式空间的
内容,D只删除多行模式空间的第一行。

2.2 追加下一行

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

[root@localhost ~]# cat 123
Consult Section 3. 1 in the Owner and Oper ator
Guide for a description of the tape dr ives
available on your system.
[root@localhost ~]# sed '/Operator$/{N;s/0wner and Operator\nGuide/Installation Guide/g}' 123
Consult Section 3. 1 in the Owner and Oper atorGuide for a description of the tape dr ives
available on your system.
[root@localhost ~]# sed '/Operator$/{N;s/0wner and Operator\nGuide/Installation Guide\n/g}' 123
Consult Section 3. 1 in the Owner and Oper ator
Guide for a description of the tape dr ives
available on your system.

2.3 多行删除

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

将多个空行减少到一行,利用d命令的版本.
/ $/{
N
/ \n$/d
}

[root@localhost ~]# cat 123
Consult Section 3. 1 in the Owner and Operator
Guide for a description of the tape dr ives
available on your system.
[root@localhost ~]# sed '/Operator$/{d;p}' 123
Guide for a description of the tape dr ives
available on your system.
[root@localhost ~]# 

[root@localhost ~]# cat 123
line 1

line 2


line 3


line 4



end
[root@localhost ~]# sed '/^$/{N;/^\n$/d}' 123
line 1

line 2
line 3

line 4
end
[root@localhost ~]# sed '/^$/{N;/^\n$/D}' 123
line 1

line 2

line 3

line 4

end
 

2.4 多行打印

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

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

[root@localhost ~]# sed '/UNIX$/{N;/\nSystem/s// Operating &/;P;D}' 123
Here are examples of the UNIX Operating 
System. Where UNIX Operating 
System appears,it should be the UNIX
Operating System.


2.5 包含那一行

模式空间是容纳当前输入行的缓冲区。还有一个称为保持空间(hold space)
的顶留(set- aside)缓冲区。模式空间的内容可以复制到保持空间,而且保持
空间的内容也可以复制到模式空间。有一组命令用于在保持空间和模式空间之
间移动数据。保持空间用于临时存储。单独的命令不能寻址保持空间或者更改
它的内容。
保持空间最常的用途是,当改变模式空间中的原始内容时,用于保留当前输入
行的副本。影响模式空间的命令有:

命令 缩写 功能
Hold h或H 将模式空间的内容复制或追加到保持空间
Get g或G 将保持空间的内容复制或追加到模式空间
Exchange x 交换保持空间和模式空间的内容
[root@localhost ~]# cat 123
1
2
11
22
111
222
[root@localhost ~]# sed '/1/{h;d}' 123
2
22
222
[root@localhost ~]# sed '/1/{h;d};/2/{G}' 123
2
1
22
11
222
111
[root@localhost ~]# sed '/1/{h};/2/{G}' 123
1
2
1
11
22
11
111
222
111

2.6 大写转换

上一草我们介绍了转换命令(y),开且描述了在一行.上如何将小与子母转换为
大写字母。因为y命令作用于模式空间的所有内容,所以对行的一部分进行逐
字转换有点繁琐。尽管这有点令人费解,但也是可能的,正如下面的示例所演
示那样。
当编写程序设计指南时,我们发现语句的名字输入不一致,它们应该都为大写
字母,但是有一些是小写字母另一些的首字母却是大写的。虽然任务很简单,
就是将语句的名字改成大写,但是这里有将近100条语句。编写如何之多的显
式替换似乎是作件冗长乏味的工作。

s/find the Match statement/find the MATCH statement/g

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

[root@localhost ~]# cat 123
find the Match statement
Consult the Get statement.
Using the Read statement to retr ieve data
[root@localhost ~]# sed -r '/the .* statement/{h;s/.*the(.*)statement.*/\1/g}' 123
 Match 
 Get 
 Read 

[root@localhost ~]# sed -r '/the .* statement/{h;s/.*the(.*)statement.*/\1/g;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/}' 123
 MATCH 
 GET 
 READ
[root@localhost ~]# sed -r '/the .* statement/{h;s/ .*the (.*)statement.*/\1/g;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G}' 123
FINDMATCH 
find the Match statement
CONSULTGET 
Consult the Get statement.
USINGREAD 
Using the Read statement to retr ieve data
[root@localhost ~]# sed -r '/the .* statement/{h;s/.*the (.*) statement.*/\1/g;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/(.*)\n(.*the ).*(statemant.*)/\2\1\3/}' 123
MATCH
find the Match statement
Consult the Get statement.
Using the Read statement to retrieve data
[root@localhost ~]# 




这篇关于sed与awk命令的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程