Linux 文本处理三剑客:grep、sed 与 awk
Linux 文本处理三剑客:grep、sed 与 awk
在 Linux 系统中,grep
、sed
、awk
并称“文本处理三剑客”,分别承担“筛选”“编辑”“字段分析”的核心角色。
一、grep:文本筛选工具——快速定位目标内容
grep
(Global Regular Expression Print)的核心功能是根据字符串或正则表达式过滤文本,逐行扫描输入内容,输出符合匹配规则的行,是日常运维中“找内容”的首选工具。
核心用法与完整解释
# 创建实例文档
[root@ansible ~]# cat > /tmp/services << EOF
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
EOF[root@ansible ~]# 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
用法格式 | 功能描述 | 实操案例 | 案例解释 |
---|---|---|---|
grep "字符串" 文件名 | 筛选包含指定字符串的所有行 | grep "blp5" /tmp/services | 从 /tmp/services 文件中,找出所有包含“blp5”的服务配置行,适用于快速定位特定服务信息。 |
grep -v "字符串" 文件名 | 排除包含指定字符串的行(反向筛选) | grep -v "udp" /tmp/services | -v 选项表示“反向匹配”,此命令会排除所有含“udp”的 UDP 服务行,仅保留 TCP 服务行,常用于过滤无用信息。 |
grep ^"字符串" 文件名 | 筛选以指定字符串开头的行 | grep ^"blp5" /tmp/services | ^ 是正则中的“行首锚定符”,仅匹配“blp5”位于行首的行(即服务名恰好为“blp5”的行),避免匹配“xblp5”等包含但非开头的情况。 |
grep "字符串"$ 文件名 | 筛选以指定字符串结尾的行 | grep "locator"$ /tmp/services | $ 是正则中的“行尾锚定符”,仅匹配“locator”位于行尾的行,适用于查找描述信息以特定词结尾的配置。 |
grep ^$ 文件名 | 筛选文件中的空行 | grep ^$ /tmp/services | ^$ 表示“行首到行尾无任何字符”,即空行,常用于统计文件中空行数量或清理空行前的检查。 |
grep -i "字符串" 文件名 | 不区分大小写筛选 | grep -i "ERROR" /var/log/messages | -i 选项忽略字符大小写,此命令会匹配“error”“Error”“ERROR”等所有大小写组合的错误日志,避免因大小写差异漏筛。 |
grep -o "模式" 文件名 | 仅显示匹配的部分内容(而非整行) | grep -o "[0-9]\+" /tmp/services | -o 选项表示“仅输出匹配到的内容”,[0-9]\+ 匹配1个及以上数字,此命令会从服务配置中提取所有端口号(仅数字部分),适用于单独获取特定字段。 |
二、sed:流式编辑工具——批量修改文本内容
sed
(Stream Editor)是一款流式文本编辑器,其核心工作原理是:
- 逐行读取文本到临时缓冲区(称为“模式空间”);
- 按用户指定的命令(如替换、删除、新增)处理缓冲区中的内容;
- 将处理后的内容输出到屏幕(默认不修改原文件);
- 清空模式空间,读取下一行,重复循环直到文件末尾。
若需修改原文件,需使用 -i
选项(建议加备份,如 sed -i.bak
);若需复杂编辑,可结合正则表达式与多命令组合。
1. 核心基础:选项、命令与地址(含原理解释)
常用选项(作用与使用场景)
选项 | 功能描述 | 适用场景 |
---|---|---|
-n | 不自动打印模式空间内容,需用 p 命令显式打印 | 仅需输出特定行(如打印匹配行),避免默认输出所有行导致冗余。 |
-e | 执行多个编辑表达式(多命令组合) | 需同时执行多个操作(如先删除再替换),用 -e 分隔不同命令。 |
-f | 从指定文件读取编辑动作 | 编辑逻辑复杂(如10+条命令),可将命令写入脚本文件,用 -f 脚本名 执行,提高可维护性。 |
-i | 直接修改原文件(默认不修改) | 需批量修改文件内容(如配置文件替换),使用前建议备份(sed -i.bak ),避免误操作无法恢复。 |
-r | 使用扩展正则表达式 | 需使用 + (1次及以上)、? (0次或1次)、() (分组)等扩展正则符号,无需手动转义,简化命令。 |
关键命令(功能与原理)
命令 | 功能描述 | 原理说明 |
---|---|---|
s/regexp/replace/ | 字符串替换(默认替换每行第一个匹配项) | s 表示“substitute(替换)”,格式为“s/旧内容/新内容/”,若加 g (如 s/blp5/test/g ),表示“全局替换”(替换每行所有匹配项)。 |
p | 打印当前模式空间的内容 | 需配合 -n 选项使用,否则会重复输出(默认输出+p 命令输出),适用于仅打印特定行(如匹配行、指定行)。 |
d | 删除当前模式空间的内容,直接进入下一行处理 | 删除后不会输出被删行,适用于清理无用内容(如注释行、空行),注意:d 会终止当前行的后续命令执行,直接读下一行。 |
a \text | 在当前行后追加指定文本 | a 表示“append(追加)”,\ 后接要追加的文本,追加内容会作为新行显示在当前行下方,适用于批量添加注释或说明。 |
i \text | 在当前行前插入指定文本 | i 表示“insert(插入)”,与 a 相反,插入内容会作为新行显示在当前行上方,适用于在特定行前添加配置项。 |
c \text | 用指定文本替换当前行的所有内容 | c 表示“change(修改)”,会覆盖当前行的所有内容,适用于批量替换整行配置(如将旧服务名行替换为新配置)。 |
r 文件名 | 从指定文件读取内容,追加到当前行后 | r 表示“read(读取)”,会将外部文件的所有内容追加到匹配行后,适用于批量导入模板内容(如在所有服务行后追加通用注释)。 |
w 文件名 | 将匹配行写入指定文件(备份匹配内容) | w 表示“write(写入)”,会将所有匹配行保存到目标文件,原文件内容不变,适用于提取特定内容到新文件(如备份某类服务配置)。 |
n/N | n :读取下一行到模式空间;N :追加下一行到模式空间 | n 会替换模式空间内容(丢弃当前行,读下一行);N 会保留当前行,将下一行以换行符 \n 追加到模式空间,适用于处理跨多行内容。 |
地址格式(指定命令作用的行,核心是“精准定位”)
地址格式 | 功能描述 | 原理与示例 |
---|---|---|
number | 指定行号(单一行) | 直接定位到某一行,如 1 表示第一行、5 表示第五行,适用于修改已知行号的配置(如修改第一行的注释)。 |
addr1,addr2 | 行范围(从 addr1 到 addr2 ) | 如 1,3 表示第1到3行、/blp5/,/com/ 表示从“blp5”行到“com”行,适用于批量处理连续的多行内容。 |
addr1,+N | 从 addr1 行开始,向后 N 行 | 如 /blp5/,+1 表示“blp5”行及后面1行(共2行),适用于处理匹配行及其附近的行(如修改服务行及对应的注释行)。 |
first~step | 从 first 行开始,每 step 行(间隔行) | 如 1~2 表示第1、3、5…行(奇数行)、2~2 表示第2、4、6…行(偶数行),适用于批量处理间隔行(如删除所有奇数行)。 |
/regexp/ | 正则匹配行(仅作用于符合正则的行) | 如 /^blp5/ 表示仅作用于以“blp5”开头的行,适用于按内容而非行号定位(如修改所有“blp5”服务的配置)。 |
$ | 匹配最后一行 | 仅作用于文件的最后一行,适用于修改文件末尾的配置(如在最后一行前添加新服务)。 |
2. 文档全案例+详细解释(以 /tmp/services
为例)
案例1:打印操作(p
命令)——精准输出特定行
打印操作的核心是用 -n
抑制默认输出,配合 p
命令显式打印目标行,避免冗余内容干扰。
(1)打印以“blp5”开头的行
[root@ansible ~]# cat /tmp/services | sed -n '/^blp5/p'
blp5 48129/tcp # Bloomberg locator
blp5 48129/udp # Bloomberg locator
解释:/^blp5/
是正则地址,匹配以“blp5”开头的行;-n
抑制默认输出,p
打印匹配行。此命令精准提取“blp5”服务的 TCP 和 UDP 配置行,用于单独查看该服务的完整配置。
(2)打印第一行
[root@ansible ~]# cat /tmp/services | sed -n '1p'
nimgtw 48003/udp # Nimbus Gateway
解释:1
是行号地址,直接定位第一行;p
打印该行。适用于查看文件开头的配置(如首行注释、第一个服务)。
(3)打印第一行至第三行
[root@ansible ~]# 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
解释:1,3
是行范围地址,覆盖第1到3行;p
打印该范围的所有行。适用于查看文件开头的连续配置(如前3个服务)。
(4)打印奇数行
[root@ansible ~]# seq 10 | sed -n '1~2p'
1
3
5
7
9
解释:1~2
是间隔地址,1
表示起始行,2
表示步长(每2行取1行),即第1、3、5…行(奇数行);seq 10
生成1-10的数字,此命令用于快速提取奇数序列,也可用于文件中提取奇数行内容。
(5)打印匹配行及后一行
[root@ansible ~]# cat /tmp/services | sed -n '/blp5/,+1p'
blp5 48129/tcp # Bloomberg locator
blp5 48129/udp # Bloomberg locator
解释:/blp5/,+1
表示“匹配‘blp5’的行,及该行后面1行”;p
打印这两行。因“blp5”服务有2行(TCP和UDP),此命令恰好提取该服务的完整配置,避免漏行。
(6)打印最后一行
[root@ansible ~]# cat /tmp/services | sed -n '$p'
iqobject 48619/udp # iqobject
解释:$
是行号地址,代表最后一行;p
打印该行。适用于查看文件末尾的配置(如最后一个服务)。
(7)不打印最后一行
[root@ansible ~]# 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# 输出除最后一行外的所有内容
解释:$!
表示“除最后一行外的所有行”(!
是“取反”符号);p
打印这些行。适用于排除文件末尾的无用内容(如末尾空行、临时配置)。
(8)匹配范围打印(正则地址范围)
# 从“blp5”行到“com”行
[root@ansible ~]# 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@ansible ~]# 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
解释:/^blp5/,/^com/
是“正则地址范围”,从“以blp5开头”的行开始,到“以com开头”的行结束,适用于提取两个特征行之间的内容;/blp5/,$
表示从“含blp5”的行到最后一行,适用于提取某服务之后的所有配置。
(9)引用系统变量打印(动态地址)
[root@ansible ~]# a=1
[root@ansible ~]# cat /tmp/services | sed -n ''$a',3p'
nimgtw 48003/udp # Nimbus Gateway
3gpp-cbsp 48049/tcp # 3GPP Cell Broadcast Service Protocol
isnetserv 48128/tcp # Image Systems Network Services# 或用双引号包裹
[root@ansible ~]# cat /tmp/services | sed -n "$a,3p"
nimgtw 48003/udp # Nimbus Gateway
3gpp-cbsp 48049/tcp # 3GPP Cell Broadcast Service Protocol
isnetserv 48128/tcp # Image Systems Network Services
解释:''$a',3p
中,$a
是系统变量(值为1),通过单引号拼接,最终地址为“1,3”,打印第1-3行;也可直接用双引号包裹("$a,3p"
),让变量直接解析。适用于动态指定起始行(如根据脚本参数决定打印范围)。
案例2:删除操作(d
命令)——清理无用内容
删除操作无需 -n
选项,d
命令会直接删除模式空间中的行,不输出被删行,仅输出剩余行。
(1)删除含“blp5”的行
[root@ansible ~]# 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# 输出排除“blp5”行后的所有内容
解释:/blp5/
匹配所有含“blp5”的行,d
命令删除这些行,适用于清理某类无用服务配置。
(2)删除第一行
[root@ansible ~]# 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# 输出删除第一行后的所有内容
解释:1
定位第一行,d
删除该行,适用于移除文件开头的无用注释或配置。
(3)删除奇数行
[root@ansible ~]# 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
解释:1~2
定位奇数行,d
删除这些行,仅保留偶数行,适用于筛选间隔行内容(如保留UDP服务行,假设UDP服务在偶数行)。
(4)删除1-3行
[root@ansible ~]# 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# 输出删除1-3行后的所有内容
解释:1,3
定位第1-3行,d
删除这些行,适用于批量清理文件开头的连续无用配置。
(5)清理httpd配置文件(删注释/空行)
[root@rhel8 ~]# sed '/^#/d;/^$/d' /etc/httpd/conf/httpd.conf | sed -r '/[[:space:]]+#/d'
解释:
- 第一个
sed
:/^#/d
删除以“#”开头的注释行,/^$/d
删除空行; - 第二个
sed -r
:/[[:space:]]+#/d
删除“空格+#”的行内注释(如Listen 80 # 监听80端口
),-r
支持扩展正则[[:space:]]+
(1个及以上空格); - 整体作用是清理 httpd 配置中的所有注释和空行,仅保留有效配置行,便于快速查看核心配置。
案例3:替换操作(s///
命令)——批量修改内容
替换操作是 sed
最常用的功能,核心格式为 s/旧内容/新内容/[选项]
,g
选项表示全局替换,p
选项表示打印替换后的行。
(1)替换“blp5”为“test”(单行单替换)
[root@ansible ~]# 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# 输出每行第一个“blp5”替换为“test”的内容
解释:s/blp5/test/
表示“将每行中第一个‘blp5’替换为‘test’”,若某行有多个“blp5”,仅替换第一个;不加 g
适用于仅修改每行首个匹配项的场景。
(2)全局替换“blp5”为“test”
[root@ansible ~]# cat /tmp/services | sed 's/blp5/test/g'
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
是“global(全局)”的缩写,此命令会替换每行中所有“blp5”为“test”,适用于批量修改所有匹配内容(如批量重命名服务名)。
(3)替换开头“blp5”并打印
[root@ansible ~]# cat /tmp/services | sed -n 's/^blp5/test/p'
test 48129/tcp # Bloomberg locator
test 48129/udp # Bloomberg locator
解释:s/^blp5/test/
仅替换以“blp5”开头的内容为“test”,-n
抑制默认输出,p
打印替换后的行,适用于验证替换结果(仅看修改后的目标行)。
(4)引用匹配内容替换(&
符号)
# 在48049后加.123
[root@ansible ~]# 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
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@ansible ~]# echo '10.10.10.1 10.10.10.2' | sed -r 's/[^ ]+/"&"/g'
"10.10.10.1" "10.10.10.2"
解释:&
是 sed
中的特殊符号,表示“引用当前匹配到的内容”:
- 第一个命令:
48049
匹配端口号,&.123
表示“在匹配到的48049后加.123”,适用于给特定字段追加内容; - 第二个命令:
[^ ]+
匹配非空格的连续字符(即IP地址),"&"
给匹配到的IP加双引号,g
全局替换,适用于批量格式化字段(如给所有IP加引号)。
(5)限定行范围替换“blp5”
[root@ansible ~]# 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行的“blp5”替换为“test”,后5行不变
解释:1,5
限定替换范围为第1-5行,仅修改该范围内的“blp5”,适用于仅批量修改文件某部分内容(如前半段配置)。
(6)条件替换(先匹配行,再替换)
[root@ansible ~]# 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# 仅在含“48129/tcp”的行中,将“blp5”替换为“test”
解释:/48129\/tcp/
是条件地址(\/
转义 /
,避免与分隔符冲突),仅对包含“48129/tcp”的行执行替换,适用于精准修改特定条件下的内容(如仅修改某服务的TCP配置行)。
(7)二次替换(同时执行多个替换)
[root@ansible ~]# 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# 同时执行两个替换:“blp5→test”和“3g→4g”
解释:用 ;
分隔多个替换命令,按顺序执行,适用于需要同时修改多个内容的场景(如同时重命名两个服务名)。
(8)分组替换(正则分组+引用)
# 在480开头端口后加test
[root@ansible ~]# cat /tmp/services | sed -r 's/(.*)(480.*)(#.*)/\1\2test \3/'
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@ansible ~]# 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
解释:-r
支持扩展正则的分组功能 ()
,\1
\2
表示引用第1、2个分组的内容:
- 第一个命令:
(.*)
(分组1:端口前内容)、(480.*)
(分组2:480开头的端口)、(#.*)
(分组3:#及后面的注释),\1\2test \3
表示在分组2后加“test”; - 第二个命令:
(\<[0-9]+\>)
(分组2:端口号,\<
\>
表示单词边界)、(tcp|udp)
(分组3:协议),\1\3\/\2\4
表示将“端口/协议”改为“协议/端口”,适用于字段位置互换。
案例4:多重编辑(多命令组合)
# 删除1-4行,并替换剩余行的blp5为test
[root@ansible ~]# 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@ansible ~]# 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
解释:-e
选项用于执行多个独立命令(也可用 ;
分隔),先执行 1,4d
删除第1-4行,再执行 s/blp5/test/
替换剩余行的“blp5”,适用于复杂编辑场景(先删后改)。
案例5-11:添加内容、读写文件、模式空间操作等(全案例+解释)
限于篇幅,此处仅保留核心逻辑解释,实操命令与文档完全一致:
- 添加内容(
a/i/c
):a
追加(后)、i
插入(前)、c
替换(整行),适用于批量添加注释或新配置; - 读写文件(
r/w
):r
从外部文件读内容追加,w
将匹配行写入新文件,适用于导入模板或备份特定内容; - 模式空间操作(
n/N/P/D
):n/N
处理多行内容,P/D
操作模式空间首行,适用于跨多行编辑(如合并行、删除首行); - 保持空间操作(
h/H/g/G/x
):保持空间是独立于模式空间的缓冲区,用于暂存内容,适用于复杂的内容迁移(如将A行内容复制到B行)。
三、awk:字段处理工具——结构化数据分析
awk
是一款具备编程语言特性的文本处理工具,其核心优势是“按字段处理文本”:
- 默认以“换行符”分隔“记录”(每行是一条记录);
- 默认以“空格/制表符”分隔“字段”(每行中的列);
- 用
$1
$2
… 引用第1、2…个字段,$0
引用整行; - 支持变量、循环、条件判断、函数,适用于结构化数据的提取、计算与报表生成。
1. 核心基础:选项、模式与字段处理(含解释)
常用选项
选项 | 功能描述 | 解释与场景 |
---|---|---|
-F 分隔符 | 指定字段分隔符 | 如 -F ':' 处理 /etc/passwd (冒号分隔),-F '[/#]' 支持多分隔符(/或#),适用于非空格分隔的文件。 |
-f 脚本文件 | 从文件读取awk程序 | 编辑逻辑复杂时,将命令写入脚本文件(如 test.awk ),用 -f test.awk 执行,提高可维护性。 |
-v 变量=值 | 定义awk变量 | 如 -v a=123 ,在awk中使用变量 a ,适用于传递外部参数到awk程序。 |
--profile=[file] | 将awk命令格式化保存到文件 | 自动生成规范化的awk脚本(默认 awkprof.out ),适用于调试复杂awk程序。 |
常用模式(awk的“执行条件”)
模式 | 功能描述 | 解释与场景 |
---|---|---|
BEGIN{} | 处理文本前执行 | 用于初始化变量、打印表头(如 BEGIN{print "Service\tPort"} ),仅执行一次,不依赖输入文本。 |
END{} | 处理文本后执行 | 用于统计结果、打印表尾(如 END{print "共" NR "行数据"} ),NR 是awk内置变量,代表“当前记录号(行号)”。 |
/regexp/ | 正则匹配行 | 仅处理符合正则的行(如 /tcp/ 仅处理含“tcp”的行),适用于按内容筛选记录。 |
逻辑运算 | 多条件组合 | pattern && pattern (逻辑与)、`pattern |
2. 文档全案例+详细解释
案例1:从文件读取awk程序
# 创建awk文件
[root@ansible ~]# echo '{print $2}' > /root/test.awk[root@ansible ~]# cat test.awk
{print $2}[root@ansible ~]# 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
解释:test.awk
中 {print $2}
表示“对每一条记录(每行),打印第2个字段”;-f test.awk
指定从该文件读取命令。此命令从服务配置中提取所有端口+协议字段(第2列),适用于批量获取特定字段。
案例2:指定分隔符提取字段
(1)单分隔符(处理 /etc/passwd
)
[root@ansible ~]# awk -F ':' '{print $1}' /etc/passwd
root
bin
daemon
****省略****
rpcuser
saslauth
apache
解释:-F ':'
指定分隔符为冒号,/etc/passwd
每行格式为“用户名:密码:UID:…”,$1
引用第1个字段(用户名),适用于提取系统用户名列表。
(2)多分隔符(/或#)
[root@ansible ~]# tail -n3 /tmp/services | awk -F'[/#]' '{print $3}'com-bardac-dwiqobjectiqobject
解释:-F'[/#]'
指定分隔符为“/”或“#”,服务配置行格式为“服务名 端口/协议 # 描述”,按此分隔后:
$1
:服务名+端口(如“com-bardac-dw 48556”);$2
:协议(如“udp”);$3
:描述(如“com-bardac-dw”);
此命令提取第3个字段(描述),适用于多分隔符场景下的字段提取。
案例3:变量赋值与引用
# 直接定义变量
[root@ansible ~]# awk -v a=123 'BEGIN{print a}'
123# 引用系统变量
[root@ansible ~]# a=123
[root@ansible ~]# awk -v a=$a 'BEGIN{print a}'
123
解释:-v a=123
在awk中定义变量 a
并赋值;引用系统变量时,-v a=$a
将系统变量 a
的值传递到awk变量 a
中。适用于在awk中使用外部参数(如脚本中的变量)。
案例4:BEGIN
与 END
模式(生成报表)
# 打印表头与表尾
[root@ansible ~]# awk -v a=$a 'BEGIN{print a}'
123
[root@ansible ~]# tail /tmp/services | awk '
> BEGIN{print "Service\t\tPort\t\tDescription\n==="}
> {print $1 "\t\t" $2 "\t" $3}
> END{print "===\n共" NR "行数据"}
> '
Service Port Description
===
nimgtw 48003/udp #
3gpp-cbsp 48049/tcp #
isnetserv 48128/tcp #
isnetserv 48128/udp #
blp5 48129/tcp #
blp5 48129/udp #
com-bardac-dw 48556/tcp #
com-bardac-dw 48556/udp #
iqobject 48619/tcp #
iqobject 48619/udp #
===
共10行数据
解释:
BEGIN{}
:处理文本前打印表头(服务名、端口、描述),用\t
对齐;- 中间命令:对每行打印第1(服务名)、2(端口)、3(描述前半部分)字段;
END{}
:处理完所有行后,打印表尾和总行数(NR
记录总行数);
整体生成结构化的服务报表,适用于数据可视化展示。
案例5:正则与逻辑匹配
(1)逻辑与(筛选blp5且tcp的行)
[root@ansible ~]# cat /tmp/services | awk '/blp5/ && /tcp/{print $0}'
blp5 48129/tcp # Bloomberg locator
解释:/blp5/ && /tcp/
表示“同时满足含blp5和含tcp”,仅打印符合条件的行,适用于精准筛选多条件组合的记录。
(2)匹配范围(从blp5行到com行)
[root@ansible ~]# cat /tmp/services | awk '/^blp5/,/^com/'
blp5 48129/tcp # Bloomberg locator
blp5 48129/udp # Bloomberg locator
com-bardac-dw 48556/tcp # com-bardac-dw
解释:/^blp5/,/^com/
是范围模式,从“以blp5开头”的行开始,到“以com开头”的行结束,适用于提取两个特征行之间的所有记录。
四、总结
- grep:“筛选工具”,快速定位目标行,适用于找内容;
- sed:“编辑工具”,批量修改文本(替换、删除、新增),适用于改内容;
- awk:“分析工具”,按字段处理结构化数据(提取、计算、报表),适用于析内容。
掌握三者的配合(如 grep
筛选 → sed
修改 → awk
分析),可应对 Linux 文本处理的绝大多数场景,大幅提升运维效率。