当前位置: 首页 > news >正文

文本处理三剑客——grep、sed、awk

文本处理三剑客——grep、sed、awk

一、grep

以下是 grep 命令常用选项及功能的表格说明:
命令格式功能描述
grep "字符串"过滤并显示包含指定“字符串”的行
grep -v "字符串"反向过滤,显示不包含指定“字符串”的行
grep ^"字符串"过滤并显示以指定“字符串”开头的行
grep "字符串"$过滤并显示以指定“字符串”结尾的行
grep ^$过滤并显示空行(仅包含换行符的行)
grep -i "字符串"过滤时不区分大小写,匹配大小写不同的相同字符
grep -o "字符串"仅显示每行中与“字符串”匹配的部分,而非整行

二、sed

1、sed简介

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容发送往屏幕。然后读入下行,执行下一个循环。
如果没有诸如“D”的特殊命令,那会在两个循环之间清空模式空间,但不能清除保留空间。这样不断重复,直到文件末尾。(文件内容并没有改变,除非你使用重定向存储输出或-i)

2、选项
以下是 sed 命令常用选项及其说明的表格:
选项功能描述
-n不打印模式空间(仅显示经过处理的行,默认情况下 sed 会打印输入内容)
-e直接在命令行中指定要执行的脚本或表达式,用于处理输入数据
-f从指定文件中读取 sed 动作(脚本)并执行
-i直接修改原文件内容(不创建备份),若需备份可使用 -i.bak 形式
-r启用扩展正则表达式支持(无需对 ?+() 等元字符转义)
3、命令
以下是 sed 常用核心命令(动作)及其功能描述的表格:
sed 命令功能描述
s/regexp/replace/替换字符串:用 replace 替换模式空间中匹配 regexp(正则表达式)的内容
p打印当前模式空间中的内容(常与 -n 搭配,避免重复输出)
P(大写)仅打印模式空间中的第一行(若模式空间包含多行,如通过 N 追加的内容)
d删除当前模式空间中的内容,直接开始下一次循环(不打印被删除行)
D(大写)删除模式空间中的第一行,若剩余内容非空则继续处理,否则开始下一次循环
=打印当前模式空间对应行的行号(行号单独占一行输出)
a \text在当前行的下方追加指定文本 text\ 用于分隔命令与文本)
i \text在当前行的上方插入指定文本 text\ 用于分隔命令与文本)
c \text用指定文本 text 替换当前选中的行(整行替换为 text
q立即退出 sed 脚本,不再处理后续输入行
r filename从指定文件 filename 中读取内容,追加到当前模式空间对应行的下方
h将模式空间中的内容覆盖复制到保持空间(覆盖原有保持空间内容)
H将模式空间中的内容追加到保持空间(原有保持空间内容后加换行再追加)
g将保持空间中的内容覆盖复制到模式空间(覆盖原有模式空间内容)
G将保持空间中的内容追加到模式空间(原有模式空间内容后加换行再追加)
x交换模式空间与保持空间中的内容(两者内容互换)
l(小写L)打印模式空间中的行,并显示控制字符(如换行符用 $ 标记,Tab 用 \t 等)
n读取下一行输入到模式空间,覆盖原有模式空间内容,然后继续执行后续命令
N读取下一行输入,追加到模式空间末尾(与原有内容用换行分隔,形成多行模式空间)
w filename将当前模式空间中的内容写入到指定文件 filename(若文件存在会覆盖)
!对匹配条件取反,仅对“不满足匹配条件”的行执行后续命令(如 2!d 表示不删除第2行)
&在替换命令(s/../../)中引用“已匹配 regexp 的字符串”(如 s/abc/[&]/ 会将 abc 替换为 [abc]
4、地址
以下是 sed 中常用的地址(行选择)表示方式及其说明的表格:
地址格式描述
first~step从第 first 行开始,每隔 step(步长) 行匹配一次(如 1~2 匹配第1、3、5…行)
$匹配最后一行
/regexp/匹配所有能被正则表达式 regexp 匹配到的行
number仅匹配指定行号的行(如 5 只匹配第5行)
addr1,addr2匹配从 addr1 行开始到 addr2 行结束的所有行(闭区间)
addr1,+Naddr1 行开始,向后包含 N 行(共 N+1 行,如 3,+2 匹配3、4、5行)
addr1,~Naddr1 行开始,匹配到第一个能被 N 整除的行结束(如 2,~3 匹配2到3行)

5、案例

案例一:
先定义一个原始数据的文本文件
[root@stw ~]# vim /tmp/services
[root@stw ~]# cat /tmp/services
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(1)打印匹配blp5开头的行
[root@stw ~]# cat /tmp/services | sed -n '/^blp5/p'
//-n:不打印模式空间,p:打印当前的模式空间  /^blp5/:以blp5开头
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
(2)打印第一行
[root@stw ~]# cat /tmp/services | sed -n '1p'
nimgtw 		48003/udp 		# Nimbus Gateway
(3)打印第一行至第三行
[root@stw ~]# cat /tmp/services | sed -n '1,3p'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services[root@stw ~]# cat /tmp/services | sed -n '1,~3p'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
(4)打印奇数行
[root@stw ~]# cat /tmp/services | sed -n '1~2p'   //从第一行开始,每隔两行输出
nimgtw 		48003/udp 		# Nimbus Gateway
isnetserv 		48128/tcp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
[root@stw ~]# seq 10 | sed -n '1~2p'
1
3
5
7
9
(5)打印偶数行
[root@stw ~]# cat /tmp/services | sed -n '2~2p'
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/udp 		# iqobject
[root@stw ~]# seq 10 | sed -n '2~2p'
2
4
6
8
10
(6)打印匹配行及后一行
[root@stw ~]# cat /tmp/services | sed -n '/blp5/,+1p'
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
(7)打印最后一行
[root@stw ~]# cat /tmp/services | sed -n '$p'
iqobject 		48619/udp 		# iqobject
(8)不打印最后一行
[root@stw ~]# cat /tmp/services | sed -n '$!p'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
[root@stw ~]# cat /tmp/services | sed -n '!$p'
sed: -e expression #1, char 2: unknown command: `$'
//!要写在$的后面,p的前面
(9)匹配范围(打印以/blp5/开头,/com/结束的行)
[root@stw ~]# cat /tmp/services | sed -n '/^blp5/,/^com/p'
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
匹配blp5所在行到最后一行
[root@stw ~]# cat /tmp/services | sed -n '/blp5/,$p'
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(10)引用系统变量,用引号
[root@stw ~]# cat /tmp/services | sed -n ''$a',3p'  //调用变量$a
sed: -e expression #1, char 1: unknown command: `,'
[root@stw ~]# export a=2    //手动定义变量a为2
[root@stw ~]# cat /tmp/services | sed -n ''$a',3p'  //打印第二行到第三行
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
[root@stw ~]# export a=2
[root@stw ~]# cat /tmp/services |sed -n "$a,3p"
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
案例二:删除匹配
(1)删除带有/blp5/的行
[root@stw ~]# cat /tmp/services | sed '/blp5/d'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(2)删除第一行
[root@stw ~]# cat /tmp/services | sed '1d'
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(3)删除奇数行
[root@stw ~]# cat /tmp/services | sed '1~2d'
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/udp 		# iqobject
[root@stw ~]# seq 10 | sed '1~2d'
2
4
6
8
10
(4)删除一到三行
[root@stw ~]# cat /tmp/services | sed '1,3d'
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
打印时把匹配的打印出来,删除时把匹配的删除,删除只是不用-n选项
练习:去除空格/etc/httpd/conf/httpd.conf文件的空行或开头#号的行
(前提有这个文件)
[root@stw ~]# sed '/^#/d;/^$/d' /etc/httpd/conf/httpd.conf | sed -r '/[[:space:]]+#/d'
ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
<Directory />AllowOverride noneRequire all denied
</Directory>
DocumentRoot "/var/www/html"
<Directory "/var/www">AllowOverride NoneRequire all granted
</Directory>
<Directory "/var/www/html">Options Indexes FollowSymLinksAllowOverride NoneRequire all granted
</Directory>
<IfModule dir_module>DirectoryIndex index.html
</IfModule>
<Files ".ht*">Require all denied
</Files>
ErrorLog "logs/error_log"
LogLevel warn
<IfModule log_config_module>LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedLogFormat "%h %l %u %t \"%r\" %>s %b" common<IfModule logio_module>LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio</IfModule>CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">AllowOverride NoneOptions NoneRequire all granted
</Directory>
<IfModule mime_module>TypesConfig /etc/mime.typesAddType application/x-compress .ZAddType application/x-gzip .gz .tgzAddType text/html .shtmlAddOutputFilter INCLUDES .shtml
</IfModule>
AddDefaultCharset UTF-8
<IfModule mime_magic_module>MIMEMagicFile conf/magic
</IfModule>
EnableSendfile on
IncludeOptional conf.d/*.conf
案例三:替换(s///)
(1)替换blp5字符串为test
[root@stw ~]# cat /tmp/services | sed 's/blp5/test/'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test 			48129/tcp 		# Bloomberg locator
test 			48129/udp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
全局替换加上g
[root@stw ~]# vim /tmp/services //在任意一行blp5的后面加上一个blp5的字符串
[root@stw ~]# cat /tmp/services 
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator blp5
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
[root@stw ~]# cat /tmp/services | sed 's/blp5/test/g' //将blp5都替换成blp5
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test 			48129/tcp 		# Bloomberg locator
test 			48129/udp 		# Bloomberg locator test
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(2)替换开头是blp5的字符串并打印
[root@stw ~]# cat /tmp/services | sed -n 's/^blp5/test/p'
test 			48129/tcp 		# Bloomberg locator
test 			48129/udp 		# Bloomberg locator blp5
(3)使用&命令引用匹配内容并替换
[root@stw ~]# cat /tmp/services
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator blp5
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
[root@stw ~]# cat /tmp/services | sed  's/48049/&.123/'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049.123/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator blp5
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
IP加上双引号
[root@stw ~]# echo '10.10.10.1 10.10.10.2 10.10.10.3' | sed -r 's/[^ ]+/"&"/g'
"10.10.10.1" "10.10.10.2" "10.10.10.3"
//  /[^ ]+/:非空格的内容   /"&"/:调用非空格的内容并前后加上"
(4)对1-5行的blp5进行替换
[root@stw ~]# cat /tmp/services | sed  '1,5s/blp5/test/'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(5)对匹配行进行替换,先匹配出来48129/tcp所在行,然后再将该行的blp5字符串替换为test
[root@stw ~]# cat /tmp/services | sed '/48129\/tcp/s/blp5/test/'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(6)二次匹配替换(先将/blp5/替换为/test/,再将/3g/替换为/4g/)
[root@stw ~]# cat /tmp/services | sed 's/blp5/test/;s/3g/4g/'
nimgtw 		48003/udp 		# Nimbus Gateway
4gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test 			48129/tcp 		# Bloomberg locator
test 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(7)分组使用
[root@stw ~]# cat /tmp/services | sed -r 's/(.*)(480.*)(#.*)/\1\2test \3/'
// (.*):任意字符   \2test\:第二部分后面加上test空格
nimgtw 		48003/udp 		test # Nimbus Gateway
3gpp-cbsp 		48049/tcp 		test # 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
将第一部分和第三部分互换位置
[root@stw ~]# cat /tmp/services | sed -r 's/(.*)(480.*)(#.*)/\3\2test \1/'
# Nimbus Gateway48003/udp 		test nimgtw 		
# 3GPP Cell Broadcast Service Protocol48049/tcp 		test 3gpp-cbsp 		
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(8)将协议与端口号位置互换
[root@stw ~]# cat /tmp/services | sed -r 's/(.*)(\<[[:digit:]]+\>)\/(tcp|udp)(.*)/\1\3\/\2\4/'
nimgtw 		udp/48003 		# Nimbus Gateway
3gpp-cbsp 		tcp/48049 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		tcp/48128 		# Image Systems Network Services
isnetserv 		udp/48128 		# Image Systems Network Services
blp5 			tcp/48129 		# Bloomberg locator
blp5 			udp/48129 		# Bloomberg locator 
com-bardac-dw 	tcp/48556 		# com-bardac-dw
com-bardac-dw 	udp/48556 		# com-bardac-dw
iqobject 		tcp/48619 		# iqobject
iqobject 		udp/48619 		# iqobject
[root@stw ~]# cat /tmp/services | sed -r 's/(.*)(\<[0-9]+\>)\/(tcp|udp)(.*)/\1\3\/\2\4/'
nimgtw 		udp/48003 		# Nimbus Gateway
3gpp-cbsp 		tcp/48049 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		tcp/48128 		# Image Systems Network Services
isnetserv 		udp/48128 		# Image Systems Network Services
blp5 			tcp/48129 		# Bloomberg locator
blp5 			udp/48129 		# Bloomberg locator 
com-bardac-dw 	tcp/48556 		# com-bardac-dw
com-bardac-dw 	udp/48556 		# com-bardac-dw
iqobject 		tcp/48619 		# iqobject
iqobject 		udp/48619 		# iqobject
(9)位置调换
[root@stw ~]# echo "abc cde xyz" | sed -r  's/(.*)x/\1X/'
// x之前的abc cde 为一组,(.*)x表示abc cde x,并将x替换为X
abc cde Xyz
[root@stw ~]# echo "abc cde xxyxz" | sed -r  's/(.*)x/\1X/'
//替换最后一个x
abc cde xxyXz
[root@stw ~]# echo "abc cde xxyxz" | sed -r  's/(.*)y/\1Y/'
abc cde xxYxz
将cde和456互换位置
[root@stw ~]# echo "abc:cde;123:456" | sed -r 's/([^:]*)(;.*:)([^:]+$)/\3\2\1/'
abc:456;123:cde
//abc:中包含:不会被捕获,保留
//([^:]*):第一个捕获组,匹配非冒号字符的任意长度(包括 0),这里会匹配 "cde"
//(;.*:):第二个捕获组,匹配分号开头、中间任意字符、冒号结尾的部分,这里匹配 ";123:"
//([^:]+$):第三个捕获组,匹配结尾位置的非冒号字符(至少 1 个),这里匹配 "456"
//\3 引用第三个捕获组的内容:"456"
//\2 引用第二个捕获组的内容:";123:"
//\1 引用第一个捕获组的内容:"abc"
(10)注释匹配行后的多少行
[root@stw ~]# seq 10 |sed '/5/,+3s/^/#/'
1
2
3
4
#5
#6
#7
#8
9
10
//  /5/:匹配包含数字5的行(即第 5 行)
//  ,+3:表示从匹配行开始,再包含后面 3 行(形成一个范围):5、6、7、8行
//  s/^/#/:将匹配范围内每行的开头(^表示行首)替换为#
(11)注释指定多行
[root@stw ~]# seq 5 |sed -r '/^3|^4/s/^/#/'
1
2
#3
#4
5
//  -r 选项:启用扩展正则表达式,允许使用|等元字符而无需转义
//  /^3|^4/:匹配以3开头的行或者以4开头的行
//  s/^/#/:将匹配到的行的行首(^)替换为#
[root@stw ~]# seq 5 |sed -r 's/^3|^4/#&/'
1
2
#3
#4
5
//  替换为 #&:# 是要添加的注释符号,& 表示匹配到的整个内容(即 3 或 4)
//  当行首是 3 时,将 "3" 替换为 "#3";当行首是 4 时,将 "4" 替换为 "#4",其他行不做处理
案例四:多重编辑
(1)删除1-4行,并将剩余行的blp5替换为test
[root@stw ~]# cat /tmp/services | sed -e '1,4d' -e 's/blp5/test/'
test 			48129/tcp 		# Bloomberg locator
test 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
[root@stw ~]# cat /tmp/services |sed '1,4d;s/blp5/test/'
test 			48129/tcp 		# Bloomberg locator
test 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
案例五:添加新内容(a、i、c)
(1)在blp5上一行添加test
[root@stw ~]# cat /tmp/services |sed '/blp5/i \test'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test
blp5 			48129/tcp 		# Bloomberg locator
test
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
//i \test:这是sed的插入命令,i表示 "在匹配行之前插入"
\test表示要插入的内容是test(\是语法要求的分隔符)
(2)在blp5下一行添加test
[root@stw ~]# cat /tmp/services |sed '/blp5/a \test'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
test
blp5 			48129/udp 		# Bloomberg locator 
test
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(3)将blp5所在行替换为新行test
[root@stw ~]# cat /tmp/services |sed '/blp5/c \test'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
test
test
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(4)在指定行的下一行添加一行
[root@stw ~]# cat /tmp/services |sed '2a \test'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
test
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(5)在指定行前面和后面添加一行
[root@stw ~]# seq 5 |sed '3s/.*/txt\n&/'
1
2
txt
3
4
5
//  3:指定操作仅作用于第 3 行
//  s/.*/txt\n&/:替换表达式
//  .*:匹配整行内容(任意字符任意长度)
//  txt\n&:替换为 "txt" + 换行符 + 原行内容(&代表匹配到的整个内容)
//  将第三行的3替换为"txt"+ 换行符(\n)+ 3
[root@stw ~]# seq 5 |sed '3s/.*/&\ntest/'
1
2
3
test
4
5
//将第三行的3替换为3+"txt"+换行符(\n)
案例六:读取文件并追加到匹配行后(r)
写一个原文件
[root@stw ~]# vim d.txt
[root@stw ~]# cat d.txt
123
456
[root@stw ~]# cat /tmp/services | sed '/blp5/r d.txt'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
123
456
blp5 			48129/udp 		# Bloomberg locator 
123
456
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
案例七: 将匹配行写到文件(w)
[root@stw ~]# cat /tmp/services | sed '/blp5/w b.txt'
// 将匹配结果重定向到b.txt的文件里
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
[root@stw ~]# cat b.txt
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
案例八:读取下一行(n和N)
n 读取下一行到模式空间
N 追加下一行内容到模式空间,并以换行符\n 分隔
(1)打印匹配的下一行
[root@stw ~]# seq 5 |sed -n '/3/{n;p}' //打印第三行的下一行
4
(2)打印偶数
[root@stw ~]# seq 6 |sed -n 'n;p'
2
4
6
//sed 先读取第一行 1,执行 n 命令,获取下一行 2,此时模式空间是 2,执行 p 命令,打印模式空
//间。 现在模式空间是 2,sed 再读取 3,执行 n 命令,获取下一行 4,此时模式空间为 4,执行 p 命
//令,以此类推
(3)打印奇数
[root@stw ~]# seq 6 |sed  'n;d'
1
3
5
//读取1,执行n,得出2,执行d,删除2,得空,以此类推,读取3,执行n,得出4,执行d,删除4,得空,
//读取5时,执行n,得6,执行d,删除6
//因无-n参数,故输出1\n3\n5

执行流程详情:

  1. 输入初始化seq 6 命令首先生成 1 到 6 的数字,每个数字单独一行,形成输入流,依次为第 1 行 “1”、第 2 行 “2”、第 3 行 “3”、第 4 行 “4”、第 5 行 “5”、第 6 行 “6”,这些行按顺序传递给 sed 处理。
  2. 处理第 1 行(输入内容 “1”)
    • sed 先将第 1 行 “1” 加载到模式空间(sed 用于临时存储当前处理行的区域);
    • 执行第一个命令 nn 命令会读取输入流中的下一行(即第 2 行 “2”),并用 “2” 覆盖模式空间中原有的 “1”,此时模式空间内容变为 “2”;
    • 执行第二个命令 dd 命令会删除模式空间中的内容(即删除 “2”),随后直接进入下一轮循环,不触发任何打印操作;
    • 由于 sed-n 参数时默认会打印 “未被 d 删除的原始输入行”,而第 1 行 “1” 未被修改或删除,因此默认打印 “1”。
  3. 处理第 3 行(输入内容 “3”)
    • 上一轮循环删除第 2 行后,sed 读取输入流的下一行(第 3 行 “3”),加载到模式空间;
    • 执行 n 命令:读取下一行(第 4 行 “4”),覆盖模式空间中的 “3”,此时模式空间内容为 “4”;
    • 执行 d 命令:删除模式空间中的 “4”,进入下一轮循环,不打印;
    • 第 3 行 “3” 未被处理,默认打印 “3”。
  4. 处理第 5 行(输入内容 “5”)
    • 上一轮循环删除第 4 行后,sed 读取输入流的下一行(第 5 行 “5”),加载到模式空间;
    • 执行 n 命令:读取下一行(第 6 行 “6”),覆盖模式空间中的 “5”,此时模式空间内容为 “6”;
    • 执行 d 命令:删除模式空间中的 “6”,进入下一轮循环,不打印;
    • 第 5 行 “5” 未被处理,默认打印 “5”。
  5. 流程结束:输入流已无更多行可处理,sed 退出,最终输出结果为 “1”“3”“5”,每行单独显示。
[root@stw ~]# seq 5 |sed   'n;d'
1
3
5
注意:处理第 5 行(内容 “5”)
  • sed 读取 “5” 加载到模式空间;
  • 执行 n 命令:尝试读取下一行,但输入流已无更多内容,模式空间仍为 “5”(无新行覆盖);
  • 执行 d 命令:删除模式空间的 “5”?不,实际是:n 虽未读到新行,但仍会触发后续 d,但此时原第 5 行 “5” 未被修改,因无 -n 仍默认打印,输出 “5”。
[root@stw ~]# seq 6 |sed -n   'p;n'
1
3
5
  1. 输入准备seq 6 生成 1-6 的数字,按行依次为 1、2、3、4、5、6,传递给 sed 处理。

  2. 处理第 1 行(内容 “1”)

    • sed -n 关闭默认输出,仅通过 p 命令打印内容;
    • 执行 p 命令:打印模式空间中的 “1”;
    • 执行 n 命令:读取下一行 “2” 到模式空间,覆盖原 “1”;
    • 本轮结束,输出 “1”。
  3. 处理第 3 行(内容 “3”)

    • 上一轮 n 已读取 “2”,但因无 p 命令且 -n 关闭默认输出,不打印 “2”;
    • sed 自动读取下一行 “3” 到模式空间;
    • 执行 p 命令:打印 “3”;
    • 执行 n 命令:读取下一行 “4” 覆盖 “3”;
    • 本轮结束,输出 “3”。
  4. 处理第 5 行(内容 “5”)

    • 上一轮 n 已读取 “4”,无打印操作;
    • sed 自动读取下一行 “5” 到模式空间;
    • 执行 p 命令:打印 “5”;
    • 执行 n 命令:读取下一行 “6” 覆盖 “5”;
    • 本轮结束,输出 “5”。
  5. 流程结束:所有行处理完毕,最终输出 1、3、5,实现了 “只打印奇数行” 的效果。核心逻辑是通过 p 打印当前行,再用 n 跳过下一行,配合 -n 精准控制输出。

(4)每三行执行一次p命令
[root@stw ~]# seq 6 |sed   'n;n;p'
1
2
3
3
4
5
6
6
  1. 处理第 1 行(内容 “1”)

    • 执行第 1 个 n:读取下一行 “2” 覆盖模式空间(原 “1” 被替换)
    • 执行第 2 个 n:读取下一行 “3” 覆盖模式空间(“2” 被替换)
    • 执行 p:打印当前模式空间的 “3”
    • 因无 -n,默认打印原输入行 “1” → 输出:1(默认) + 3p命令)
  2. 处理第 4 行(内容 “4”)

    • 执行第 1 个 n:读取下一行 “5” 覆盖模式空间(“4” 被替换)
    • 执行第 2 个 n:读取下一行 “6” 覆盖模式空间(“5” 被替换)
    • 执行 p:打印当前模式空间的 “6”
    • 因无 -n,默认打印原输入行 “4” → 输出:4(默认) + 6p命令)
(5)每三行替换一次
方法1:只是把p命令改成了替换命令
[root@stw ~]# seq 6 |sed 'n;n;s/^/=/;s/$/=/'
1
2
=3=
4
5
=6=
//执行 s/^/=/ 命令:在当前模式空间内容 “3” 的开头添加 “=”,内容变为 “=3”
//执行 s/$/=/' 命令:在 “=3” 的结尾添加 “=”,内容变为 “=3=”
//第六行也一样
方法2:这次用到了地址匹配,来实现上面的效果
[root@stw ~]# seq 6 |sed '3~3{s/^/=/;s/$/=/}'
1
2
=3=
4
5
=6=
//从第 3 行开始,每隔 3 行(即第 3 行、第 6 行),在该行内容首尾各添加一个等号
注意:当执行多个 sed 命令时,有时相互会产生影响,我们可以用大括号{}把他们括起来
(6)再看下N命令的功能(N 追加下一行内容到模式空间,并以换行符\n 分隔)
[root@stw ~]# seq 5 |sed -n 'N;p'
1
2
3
4

执行流程:

  • 第 1 轮:
    • 初始读取第 1 行 “1” 到模式空间;
    • 执行 N:读取下一行 “2”,追加到模式空间,此时模式空间内容为 “1\n2”;
    • 执行 p:打印模式空间内容 → 输出 “1\n2”(即 1 和 2 各占一行)。
  • 第 2 轮:
    • sed 自动读取下一行(第 3 行 “3”)到模式空间;
    • 执行 N:读取下一行 “4”,追加到模式空间,内容变为 “3\n4”;
    • 执行 p:打印模式空间内容 → 输出 “3\n4”(即 3 和 4 各占一行)。
  • 第 3 轮:
    • sed 自动读取下一行(第 5 行 “5”)到模式空间;
    • 执行 N:尝试读取下一行,但输入流已无更多内容(第 5 行是最后一行),因此模式空间仅保留 “5”;
    • 执行 p:此时因 N 未读取到新行,模式空间只有 “5”,但由于 sed 处理机制,最后一行未被打印(或理解为 “未形成完整的两行组合”)。
[root@stw ~]# seq 6 |sed -n 'N;p'
1
2
3
4
5
6

注意:为什么第一个不打印 5 呢?
因为 N 命令是读取下一行追加到 sed 读取的当前行,当 N 读取下一行没有内容时,则退出,也不会
执行 p 命令打印当前行。
当行数为偶数时,N 始终就能读到下一行,所以也会执行 p 命令。

加一个满足条件,当 sed 执行到最后一行时,用感叹号不去执行 N 命令,随后执行 p 命令
[root@stw ~]# seq 5 |sed -n '$!N;p'
1
2
3
4
5

执行流程:

  • 处理第 1 行(内容 “1”):
    • 不是最后一行($! 条件成立),执行 N 命令,读取下一行 “2” 追加到模式空间,此时内容为 “1\n2”
    • 执行 p 命令,打印模式空间内容 → 输出 “1” 和 “2”
  • 处理第 3 行(内容 “3”):
    • 不是最后一行($! 条件成立),执行 N 命令,读取下一行 “4” 追加到模式空间,此时内容为 “3\n4”
    • 执行 p 命令,打印模式空间内容 → 输出 “3” 和 “4”
  • 处理第 5 行(内容 “5”):
    • 是最后一行($! 条件不成立),不执行 N 命令,模式空间仅为 “5”
    • 执行 p 命令,打印模式空间内容 → 输出 “5”
案例九:打印和删除模式空间第一行(P(大写)和D)
P(大写) 打印模式空间的第一行
D 删除模式空间的第一行
(1)打印奇数(P(大写) 打印模式空间的第一行)
[root@stw ~]# seq 6 |sed -n 'N;P'
1
3
5
N和D一起的应用
[root@stw ~]# seq 6 |sed 'N;D'
6
//读取1,执行N,得出1\n2,执行D,得出2,执行N,得出2\n3,执行D,得出3,依此类推,得出6
//执行N,条件失败退出,因无-n参数,故输出6

执行流程:

  • 第 1 轮

    • 初始读取第 1 行 “1” 到模式空间
    • 执行 N:读取第 2 行 “2”,模式空间内容为 “1\n2”
    • 执行 D:删除第一行 “1”,剩余 “2”,继续处理这一行
  • 第 2 轮

    (处理剩余的 “2”):

    • 执行 N:读取第 3 行 “3”,模式空间内容为 “2\n3”
    • 执行 D:删除第一行 “2”,剩余 “3”,继续处理
  • 第 3 轮

    (处理剩余的 “3”):

    • 执行 N:读取第 4 行 “4”,模式空间内容为 “3\n4”
    • 执行 D:删除第一行 “3”,剩余 “4”,继续处理
  • 第 4 轮

    (处理剩余的 “4”):

    • 执行 N:读取第 5 行 “5”,模式空间内容为 “4\n5”
    • 执行 D:删除第一行 “4”,剩余 “5”,继续处理
  • 第 5 轮

    (处理剩余的 “5”):

    • 执行 N:读取第 6 行 “6”,模式空间内容为 “5\n6”
    • 执行 D:删除第一行 “5”,剩余 “6”,继续处理
  • 第 6 轮

    (处理剩余的 “6”):

    • 执行 N:尝试读取下一行,已无内容,模式空间保持 “6”
    • 执行 D:删除第一行(仅剩的 “6” 被删除),模式空间为空
    • 循环结束,sed 默认打印最终模式空间(空)?不,实际流程中最后剩余的 “6” 会被保留并输出
提问:seq 5 |sed -n 'N;p’为什么这条命令的第二轮是从读取3开始而seq 6 |sed 'N;D’的第二轮会继续处理2
N;p 中,p 命令的作用是打印模式空间后,清空模式空间并自动读取下一行
  1. 第一轮
    • 读取第 1 行 “1” 到模式空间 → 执行 N 追加第 2 行 → 模式空间为 “1\n2”
    • 执行 p → 打印 “1\n2”,然后模式空间被清空
    • sed 自动读取下一行(第 3 行 “3”)作为新一轮处理的起始行 → 进入第二轮
  2. 第二轮
    • 以第 3 行 “3” 为起点 → 执行 N 追加第 4 行 → 模式空间为 “3\n4”
    • 执行 p → 打印 “3\n4”,模式空间清空
    • 自动读取下一行(第 5 行 “5”)→ 进入第三轮

关键p 命令打印后,模式空间会被清空,sed 会自动读取下一行作为新起点,因此第二轮从 “3” 开始

N;D 中,D 命令的作用是删除模式空间第一行后,保留剩余内容并重复当前命令集(不自动读取新行)
  1. 第一轮
    • 读取第 1 行 “1” → 执行 N 追加第 2 行 → 模式空间为 “1\n2”
    • 执行 D → 删除第一行 “1”,保留剩余的 “2” 在模式空间,且不读取新行
    • 直接用模式空间剩余的 “2” 重复执行命令集 → 进入第二轮
  2. 第二轮
    • 以模式空间剩余的 “2” 为起点 → 执行 N 追加第 3 行 → 模式空间为 “2\n3”
    • 执行 D → 删除第一行 “2”,保留 “3” → 进入第三轮

关键D 命令不会清空模式空间,而是保留剩余内容并重复处理,因此第二轮从 “2”(上一轮剩余内容)开始,而非自动读取新行

命令组合关键命令行为模式空间处理下一轮起点
N;pp 打印后清空模式空间清空,自动读取下一行新行(如 3)
N;DD 删除首行后保留剩余内容保留剩余内容,不读新行剩余内容(如 2)
案例十:保持空间操作(h与H,g与G和x)
h 复制模式空间内容到保持空间(覆盖)
H 复制模式空间内容追加到保持空间。
g 复制保持空间内容到模式空间(覆盖)
G 复制保持空间内容追加到模式空间
x 模式空间与保持空间内容互换
(1)将匹配的内容覆盖到另一个匹配
[root@stw ~]# seq 6 |sed -e '/3/{h;d}' -e '/5/g'
1
2
4
3
6
//h 把匹配的3复制到保持空间,d 删除模式空间的3。后面命令再对模式空间匹配5
//g 把保持空间的3覆盖模式空间的5
//显示的是模式空间的内容
(2)将匹配的内容放到最后
[root@stw ~]# seq 6 |sed -e '/3/{h;d}' -e '$G'
1
2
4
5
6
3
//h 把匹配的3复制到保持空间,d 删除模式空间的3
//G 把保持空间的3追加到模式空间
//$G 把保持空间的3追加到模式空间的最后
//显示的是模式空间的内容
(3)交换模式空间和保持空间
[root@stw ~]# seq 6 |sed -e '/3/{h;d}' -e '/5/x' -e '$G'
1
2
4
3
6
5
//  /3/{h;d} 把匹配的3复制到保持空间,再删除模式空间的3
//  x 模式空间与保持空间内容互换
//  /5/x 在模式空间匹配到5,并将保持空间的3与5交换,5就变成了3
//  最后把保持空间的5追加到模式空间的最后

三、awk

awk 是一个处理文本的编程语言工具,能用简短的程序处理标准输入或文件、数据排序、计算以及生成报表等等
awk 处理的工作方式与数据库类似,支持对记录和字段处理,这也是 grep 和 sed 不能实现的。
在 awk 中,缺省的情况下将文本文件中的一行视为一个记录,逐行放到内存中处理,而将一行中的某一部分作为记录中的一个字段。用 1,2,3…数字的方式顺序的表示行(记录)中的不同字段。用$后跟数字,引用对应的字段,以逗号分隔,0 表示整个行。

1、选项
以下是 awk 命令常用选项及其说明的表格:
选项功能描述
-f从指定文件中读取 awk 程序源代码(脚本)并执行
-F指定 fs 作为输入字段的分隔符(默认分隔符为任意空白字符)
-vawk 程序执行前为变量赋值(格式:-v 变量名=值
--posix启用 POSIX 标准兼容模式,遵循 POSIX 正则表达式规范
--dump-variables=[file]awk 执行时的全局变量及其值写入指定文件,默认文件名为 awkvars.out
--profile=[file]awk 语句格式化(美化)后输出到指定文件,默认文件名为 awkprof.out
2、模式
以下是 awk 常用模式(Pattern)及其功能描述的表格:
awk 常用模式功能描述
BEGIN{ }初始化模式,在 awk 读取任何输入记录之前执行,常用于设置变量、定义函数、打印表头(仅执行1次)
END{ }收尾模式,在 awk 读取并处理完所有输入记录之后执行,常用于计算结果汇总、打印最终统计信息(仅执行1次)
/regular expression/正则匹配模式,对每一行输入记录,若内容能匹配指定的正则表达式(regular expression),则执行后续关联的动作(Action)
pattern1 && pattern2逻辑“与”模式,仅当输入记录同时满足 pattern1pattern2 两个模式时,才执行后续动作
`pattern1
!pattern逻辑“非”模式,对输入记录取反判断:若记录不满足 pattern ,则执行后续动作
pattern1, pattern2范围模式,从“首次匹配 pattern1 的记录”开始,到“首次匹配 pattern2 的记录”结束,该范围内的所有记录均会执行后续动作(匹配到 pattern2 后,范围终止)
3、示例
编辑一个test.awk文件
[root@stw ~]# vim test.awk
[root@stw ~]# cat test.awk
{print $2}
[root@stw ~]# cat /tmp/services 
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
(1)从文件读取awk程序处理文件
(-f从指定文件中读取 awk 程序源代码(脚本)并执行 //默认以空格作为分隔符)
[root@stw ~]# cat /tmp/services | awk -f test.awk //读取第二部分的字段
48003/udp
48049/tcp
48128/tcp
48128/udp
48129/tcp
48129/udp
48556/tcp
48556/udp
48619/tcp
48619/udp
[root@stw ~]# vim test.awk 
[root@stw ~]# cat test.awk
{print $3}
[root@stw ~]# cat /tmp/services | awk -f test.awk   //读取第三部分的字段
#
#
#
#
#
#
#
#
#
#
(2)指定分隔符,打印指定字段
[root@stw ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
......
[root@stw ~]# awk -F ':' '{print $1}' /etc/passwd  //以:为分隔符打印第一部分的字段
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
......
还可以指定多个分隔符,作为同一个分隔符处理
[root@stw ~]# tail -n3 /tmp/services 
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject[root@stw ~]# tail -n3 /tmp/services |awk -F'[/#]' '{print $3}'com-bardac-dwiqobjectiqobject
//tail -n3 匹配倒数三行
//-F[/#] 以/或者#为分隔符
//打印第三个字段
[root@stw ~]# tail -n3 /tmp/services |awk -F'[/#]' '{print $1}'
com-bardac-dw 	48556
iqobject 		48619
iqobject 		48619
//tail -n3 匹配倒数三行
//-F[/#] 以/或者#为分隔符
//打印第一个字段
[root@stw ~]# tail -n3 /tmp/services |awk -F'[/#]' '{print $2}'
udp 		
tcp 		
udp 	
//tail -n3 匹配倒数三行
//-F[/#] 以/或者#为分隔符
//打印第二个字段
[root@stw ~]# tail -n3 /tmp/services |awk -F'[ /]+' '{print $2}'485564861948619
// tail -n3 匹配倒数三行
// -F[ /]+ 指定分隔符为 “一个或多个连续的空格()或斜杠(/)”
//[] 表示字符集合,+ 表示匹配前面字符 1 次或多次)
// 打印第二个字段
(3)变量赋值(-v:在 awk 程序执行前为变量赋值(格式:-v 变量名=值))
[root@stw ~]# awk -v a=123 'BEGIN{print a}'
123[root@stw ~]# a=123
[root@stw ~]# awk -v a=$a 'BEGIN{print a}' ////系统变量作为awk变量的值
123[root@stw ~]# awk 'BEGIN{print '$a'}'   //或使用单引号
123
(4)BEGIIN和END
BEGIN 模式是在处理文件之前执行该操作,常用于修改内置变量、变量赋值和打印输出的页眉或标题
例如:打印页眉
[root@stw ~]# tail /tmp/services |awk 'BEGIN{print "Service\t\tPort\t\t\tDescription\n==="}{print $0}'
// 这里的t代表tab键
//{print $0}:对 tail 输出的每一行(即 /tmp/services 的最后 10 行)
//原样打印整行内容($0 表示整行)Service		Port			Description
===
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
END 模式是在程序处理完才会执行
例如:打印页尾
[root@stw ~]# tail /tmp/services |awk '{print $0}END{print "===\nEND......"}'
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
===
END......
(5)格式化输出awk命令到文件
(–profile :将 awk 语句格式化(美化)后输出到指定文件,默认文件名为 awkprof.out
[root@stw ~]# tail /tmp/services |awk --profile 'BEGIN{print"Service\t\tPort\t\t\tDescription\n==="}{print $0}END{print "===\nEND......"}'
Service		Port			Description
===
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
===
END......
[root@stw ~]# cat awkprof.out # gawk profile, created Sat Sep 13 21:16:52 2025# BEGIN block(s)BEGIN {print "Service\t\tPort\t\t\tDescription\n==="}# Rule(s){print $0}# END block(s)END {print "===\nEND......"}[root@stw ~]# tail /tmp/services | awk -f awkprof.out  //引用awkprof.out文件
Service		Port			Description
===
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
===
END......
[root@stw ~]# awk -f awkprof.out /tmp/services 
Service		Port			Description
===
nimgtw 		48003/udp 		# Nimbus Gateway
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
isnetserv 		48128/udp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
com-bardac-dw 	48556/udp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
iqobject 		48619/udp 		# iqobject
===
END......
(6)/re/正则匹配
匹配包含 tcp 的行:
[root@stw ~]# cat /tmp/services |awk '/tcp/{print $0}'
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
com-bardac-dw 	48556/tcp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
[root@stw ~]# cat /tmp/services |awk '/tcp/{print $1}'  //打印tcp所在行的第一字段
3gpp-cbsp
isnetserv
blp5
com-bardac-dw
iqobject
[root@stw ~]# cat /tmp/services |awk '/tcp/{print $2}'  ////打印tcp所在行的第二字段
48049/tcp
48128/tcp
48129/tcp
48556/tcp
48619/tcp
(7)逻辑 and、or 和 not
匹配记录中包含 blp5 和 tcp 的行:
[root@stw ~]# cat /tmp/services |awk '/blp5/ && /tcp/{print $0}'
blp5 			48129/tcp 		# Bloomberg locator
匹配记录中包含 blp5 或 tcp 的行:
[root@stw ~]# cat /tmp/services |awk '/blp5/ || /tcp/{print $0}'
3gpp-cbsp 		48049/tcp 		# 3GPP Cell Broadcast Service Protocol
isnetserv 		48128/tcp 		# Image Systems Network Services
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw
iqobject 		48619/tcp 		# iqobject
不匹配开头是#和空行:
[root@stw ~]# awk '! /^#/ && ! /^$/{print $0}' /etc/httpd/conf/httpd.conf |awk '! /^ +#/{print $0}'
ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
<Directory />AllowOverride noneRequire all denied
</Directory>
DocumentRoot "/var/www/html"
<Directory "/var/www">AllowOverride NoneRequire all granted
</Directory>
<Directory "/var/www/html">Options Indexes FollowSymLinksAllowOverride NoneRequire all granted
</Directory>
<IfModule dir_module>DirectoryIndex index.html
</IfModule>
<Files ".ht*">Require all denied
</Files>
ErrorLog "logs/error_log"
LogLevel warn
<IfModule log_config_module>LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedLogFormat "%h %l %u %t \"%r\" %>s %b" common<IfModule logio_module>LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio</IfModule>CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">AllowOverride NoneOptions NoneRequire all granted
</Directory>
<IfModule mime_module>TypesConfig /etc/mime.typesAddType application/x-compress .ZAddType application/x-gzip .gz .tgzAddType text/html .shtmlAddOutputFilter INCLUDES .shtml
</IfModule>
AddDefaultCharset UTF-8
<IfModule mime_magic_module>MIMEMagicFile conf/magic
</IfModule>
EnableSendfile on
IncludeOptional conf.d/*.conf
(8)匹配范围
[root@stw ~]# cat /tmp/services |awk '/^blp5/,/^com/'
blp5 			48129/tcp 		# Bloomberg locator
blp5 			48129/udp 		# Bloomberg locator 
com-bardac-dw 	48556/tcp 		# com-bardac-dw

文章转载自:

http://uJLsGvM0.rjdjr.cn
http://tmcmKbu2.rjdjr.cn
http://PRgpQvzd.rjdjr.cn
http://27k1wYTC.rjdjr.cn
http://O6AplMIt.rjdjr.cn
http://n2iNyUH0.rjdjr.cn
http://IpeG1prp.rjdjr.cn
http://KPw4kKg3.rjdjr.cn
http://EpI0lxD7.rjdjr.cn
http://80BWmxu8.rjdjr.cn
http://sI5s4pPW.rjdjr.cn
http://swIo5wBR.rjdjr.cn
http://shPYLtBS.rjdjr.cn
http://Ok8Kbg66.rjdjr.cn
http://yI9OS8f9.rjdjr.cn
http://7Gw4XzIL.rjdjr.cn
http://yV95E7SP.rjdjr.cn
http://a7w0c5c8.rjdjr.cn
http://ercQNSw9.rjdjr.cn
http://8ZG6fe22.rjdjr.cn
http://44HwMEoI.rjdjr.cn
http://FsBR1H99.rjdjr.cn
http://7scgZ5s4.rjdjr.cn
http://ecLlRSPw.rjdjr.cn
http://Gg8WlAEJ.rjdjr.cn
http://yhr4UDOp.rjdjr.cn
http://NHm57ZNe.rjdjr.cn
http://kGxJu0UD.rjdjr.cn
http://4OoOnm3Y.rjdjr.cn
http://O6q1SDgX.rjdjr.cn
http://www.dtcms.com/a/382163.html

相关文章:

  • o2oa待办流程和已办流程表
  • 【WebSocket✨】入门之旅(三):WebSocket 的实战应用
  • 闪电科创-交通信号灯仿真SUMO
  • 【自动化】深入浅出UIAutomationClient:C#桌面自动化实战指南
  • 自定义类型:结构体、联合与枚举(1)
  • 在 Ubuntu 系统中基于 Miniconda 安装 VLLM 并启动模型 + Dify 集成指南
  • JavaWeb--day4--WebHttp协议Tomcat
  • Linux命令行的核心理念与实用指南(进阶版)
  • 机器学习-模型验证
  • 3-机器学习与大模型开发数学教程-第0章 预备知识-0-3 函数初步(多项式、指数、对数、三角函数、反函数)
  • 使用Aop和自定义注解实现SpringTask定时任务中加锁逻辑的封装
  • 远程依赖管理新范式:cpolar赋能Nexus全球协作
  • 【个人项目】【前端实用工具】OpenAPI to TypeScript 转换器
  • 贪心算法应用:物流装箱问题详解
  • 《用 TensorFlow 构建回归模型:从零开始的预测之路》
  • charles功能
  • Ceph OSD 元数据信息
  • Stanford CS336 | Assignment 2 - FlashAttention-v2 Pytorch Triotn实现
  • 【Docker】容器
  • C++ 类型推导(第一部分)
  • 联邦学习模型完成之后在验证集上面,如何判断输出正确与否
  • 优选算法---链表
  • 从理据到算法:认知语义学象似性对人工智能深层语义分析的重塑与前瞻
  • 39.网络流入门
  • PTQ 模型 量化方法
  • 基于Spring Boot的家政服务管理系统+论文示例参考
  • uniapp封装长按一直触发事件和松开后触发一次的事件(自定义事件)
  • Unity核心概念⑦:Transform
  • 【数据行业发展】可信数据空间~数据价值的新型基础设施
  • 使用“洋葱架构”构建单体应用