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

Linux 文本处理三剑客:grep、sed 与 awk

Linux 文本处理三剑客:grep、sed 与 awk

在这里插入图片描述

在 Linux 系统中,grepsedawk 并称“文本处理三剑客”,分别承担“筛选”“编辑”“字段分析”的核心角色。

一、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)是一款流式文本编辑器,其核心工作原理是:

  1. 逐行读取文本到临时缓冲区(称为“模式空间”);
  2. 按用户指定的命令(如替换、删除、新增)处理缓冲区中的内容;
  3. 将处理后的内容输出到屏幕(默认不修改原文件);
  4. 清空模式空间,读取下一行,重复循环直到文件末尾。

若需修改原文件,需使用 -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/Nn:读取下一行到模式空间;N:追加下一行到模式空间n 会替换模式空间内容(丢弃当前行,读下一行);N 会保留当前行,将下一行以换行符 \n 追加到模式空间,适用于处理跨多行内容。
地址格式(指定命令作用的行,核心是“精准定位”)
地址格式功能描述原理与示例
number指定行号(单一行)直接定位到某一行,如 1 表示第一行、5 表示第五行,适用于修改已知行号的配置(如修改第一行的注释)。
addr1,addr2行范围(从 addr1addr21,3 表示第1到3行、/blp5/,/com/ 表示从“blp5”行到“com”行,适用于批量处理连续的多行内容。
addr1,+Naddr1 行开始,向后 N 行/blp5/,+1 表示“blp5”行及后面1行(共2行),适用于处理匹配行及其附近的行(如修改服务行及对应的注释行)。
first~stepfirst 行开始,每 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/ca 追加(后)、i 插入(前)、c 替换(整行),适用于批量添加注释或新配置;
  • 读写文件(r/wr 从外部文件读内容追加,w 将匹配行写入新文件,适用于导入模板或备份特定内容;
  • 模式空间操作(n/N/P/Dn/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:BEGINEND 模式(生成报表)
# 打印表头与表尾
[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 文本处理的绝大多数场景,大幅提升运维效率。


文章转载自:

http://Xe2irO6C.ykswq.cn
http://AzgPjqUg.ykswq.cn
http://wbXEvWTz.ykswq.cn
http://jANmHVLq.ykswq.cn
http://nCMBY6do.ykswq.cn
http://o2M3Fecb.ykswq.cn
http://3rIs4esm.ykswq.cn
http://jI1X7O7I.ykswq.cn
http://IJoOaCOJ.ykswq.cn
http://7U055L9p.ykswq.cn
http://9YRE9fKg.ykswq.cn
http://iItrMow6.ykswq.cn
http://93g9uInc.ykswq.cn
http://PnkkS2QU.ykswq.cn
http://RGX74vva.ykswq.cn
http://KLKPfzzG.ykswq.cn
http://qM60O0Ye.ykswq.cn
http://WVzyjXTb.ykswq.cn
http://zILblIUU.ykswq.cn
http://eSD2yn0T.ykswq.cn
http://7NLLMQcN.ykswq.cn
http://eGOFSTDM.ykswq.cn
http://k2YgmkBN.ykswq.cn
http://wFdZbAMn.ykswq.cn
http://q4SGjL03.ykswq.cn
http://hoUf3Zqk.ykswq.cn
http://NNnrpOUl.ykswq.cn
http://YiwCAHvQ.ykswq.cn
http://fuOOG3qT.ykswq.cn
http://j4PI4cdF.ykswq.cn
http://www.dtcms.com/a/385500.html

相关文章:

  • docker-webtop+cpolar:无感远程Linux桌面方案
  • 随机森林模型:基于天气数据集的分类任务全流程解析
  • Linux vim快捷键记录
  • 聊聊大模型的self-training:从Test-time RL说起
  • 星穹无损合约:以信任为基石,开启DeFi新纪元
  • cJSON的安装和使用
  • godot+c#实现玩家的简单移动
  • 【工具】多线程任务执行函数
  • 使用 Spring Boot 搭建和部署 Kafka 消息队列系统
  • scikit-learn pipeline做数据预处理 模板参考
  • MATLAB的二维SIMPLE算法实现方腔自然对流
  • SPMI总线协议(二)
  • 全场景流畅投屏,跨 VLAN 技术成酒店智能升级核心动力
  • 5.MQ常见问题梳理
  • 数字人作为广播工具:消息透传接口的作用和实现
  • 解读50页企业运维管理体系总体规划【附全文阅读】
  • 如何离线安装docker-compose
  • 冒泡排序Java第一版
  • DevOps历程--Docker安装Jenkins详细教程
  • 《自动控制原理》第 1 章 绪论
  • 【10】C#实战篇——C# 调用 C++ dll(C++ 导出函数、C++导出类)
  • Flask框架的简单了解
  • 高性能代码优化实战与解析
  • 企业即时通讯保障企业通讯安全,提升企业部门协作效率
  • 在亚洲市场:为何CES Asia无法被复制?
  • 【cpp Trip第2站】map,set,hash
  • 菊风携手东莞银行,推进金融信创国产化进程
  • 内部类的用法
  • 设计模式(C++)详解—适配器模式(2)
  • 6.Cesium 学习