程序猿知识星球
每天提供最新IT类资讯、原创内容、运维经验和运维知识分享!偶尔还会有福利频道,免费上车,坚持不付费为原则,免费分享,大家的关注就是对我最大的支持!

Linux 三剑客定位:
grep:行过滤,搜索匹配文本
sed:流编辑器,行级增删改替换
awk:列处理、格式化、统计计算
生产环境大量用于日志分析、配置修改、数据提取。
一、grep
语法
grep [options] "pattern" filename常用参数
-i | |
-v | |
-n | |
-c | |
-o | |
-r/-R | |
-E | |
-F |
常用示例
# 查找包含error的行,显示行号,忽略大小写grep -in "error" app.log# 过滤掉注释行(#开头)和空行grep -vE '^#|^$' nginx.conf# 递归搜索/etc下包含listen的文件grep -r "listen" /etc/# 只打印匹配到的关键词本身grep -o "2026-[0-9]*-[0-9]*" app.log
✘ grep 易错点 & 实战踩坑
1.特殊字符不加转义:* . [] () 是正则元字符,直接写会被解析;想搜字面.要用\.,或者用grep -F关闭正则。
# 错误:grep "192.168.1.1" file .匹配任意字符# 正确grep -F "192.168.1.1" filegrep "192\.168\.1\.1" file
2.管道多次 grep,注意 - v 逻辑:grep "A" file | grep -v "B" 是匹配 A 并且排除 B,不要搞反顺序。
3.grep -c返回匹配行数,不是匹配字符串个数,一行多个匹配只算 1;统计字符串次数用 -o | wc -l
# 统计error出现多少次(一行多个error也计数)grep -o "error" app.log | wc -l
4.二进制文件告警:grep匹配二进制文件会提示 Binary file 匹配,加 -a 把二进制当文本处理。
5.引号:pattern 有空格、特殊符号必须加双引号 / 单引号;单引号原样,双引号会解析 shell 变量。
实战经验:排查日志优先 grep -in;清理配置文件注释空行 grep -vE '^#|^$'。
二、sed 流编辑器
sed 按行读取,模式空间处理;默认只输出到 stdout,不会改原文件! -i才真正修改磁盘文件。
语法
sed [options] '地址|规则' file常用参数
-i | -i.bak 修改同时生成备份 xxx.bak |
-n | |
-e |
sed 核心动作:
s/old/new/flags 替换
d 删除行
a 行后追加
i 行前插入
p 打印输出,配合 -n
常用示例
替换 s///
# 每行第一个匹配替换sed 's/foo/bar/' test.txt# g全局,一行全部替换sed 's/foo/bar/g' test.txt# 指定行范围:3‑10行做替换sed '3,10s/foo/bar/g' test.txt# 修改原文件,同时备份test.txt.bak(生产强烈建议备份)sed -i.bak 's/foo/bar/g' test.txt# 分隔符可以换成#,避免/转义(处理路径很方便)sed 's#/usr#/opt#g' test.txt
删除 d
sed '5d' test.txt # 删除第5行sed '2,7d' test.txt # 删除2‑7行sed '/^#/d' test.txt # 删除#开头注释行sed '/^$/d' test.txt # 删除空行sed '/error/d' test.txt # 删除包含error的行
插入追加 a i
sed '2i 这行插在第2行前面' test.txtsed '2a 这行追加在第2行后面' test.txt
-n + p 只打印匹配行
sed -n '3,6p' test.txt # 只打印3‑6行sed -n '/error/p' app.log # 打印含error的行,等价grep
✘ sed 易错点 & 实战踩坑
1.忘记 -i 以为改了文件:不加 - i 只是屏幕输出,原文件纹丝不动;生产务必优先 -i.bak 备份,防止改错无法回滚。
2.替换内容包含 / 斜杠:不要疯狂转义,改用别的分隔符 s#old#new#g。
3.macOS sed 和 Linux sed 不一样! mac 的 -i 需要传空参数 sed -i '' 's///' file,脚本跨平台要注意。
4.sed 's/old/new/' 默认只替换每行第一个;忘记 g,只替换第一个,这是最高频 bug。
5.地址范围:/start/,/end/d 正则区间匹配,一旦 end 匹配不到会删除到文件末尾!生产慎用区间删除。
6.单引号与双引号:sed 表达式尽量单引号;如果要使用 shell 变量,改用双引号。
name="test"sed "s/xxx/$name/g" file
实战经验:配置文件清理:sed -i.bak '/^#/d;/^$/d' nginx.conf;路径替换优先换分隔符#。
三、awk(最强,列处理 + 统计)
awk 是一门小型编程语言,按记录(默认一行)切割字段。
$0:整行全部内容
$1 $2 $3:第 1、2、3 列
NF:当前行总字段数
NR:当前行号
FS:输入分隔符,-F 设置
OFS:输出分隔符
BEGIN{}:处理文件之前执行
END{}:全部行读完之后执行
语法
awk [options] '条件{动作}' file常用示例
# 默认空格分割,打印第1列awk '{print $1}' test.txt# 打印1、3列awk '{print $1,$3}' test.txt# 指定冒号为分隔符,读取/etc/passwdawk -F: '{print $1,$6}' /etc/passwd# 行号大于3才输出awk 'NR>3 {print $0}' test.txt# 第3列数值大于100输出整行awk '$3>100 {print $0}' test.txt# 过滤error日志,打印第2第5列awk '/ERROR/ {print $2,$5}' app.log# 求和,第二列累加,最后输出总和awk '{sum += $2} END {print "总和="sum}' test.txt# BEGIN 初始化,END汇总awk 'BEGIN{print "开始统计"} $3>0{cnt++} END{print "符合行数:" cnt}' test.txt# 修改输出分隔符awk -F: -v OFS="|" '{print $1,$7}' /etc/passwd
✘ awk 易错点 & 实战踩坑
1. 引号必须是单引号!awk 脚本整体放单引号;双引号会被 shell 解析,语法直接错乱。
2.-F分隔符是正则,不是普通字符串。
# 按多个空格/tab分割,-F'[ \t]+'awk -F'[ \t]+' '{print $2}' file
3.数字比较 vs 字符串比较:$3>100 是数值比较;如果字段含有字母会当作 0,结果异常。
5.NF使用:print $NF打印最后一列,$(NF‑1)倒数第二列。
6.BEGIN/END:BEGIN在读取文件之前,不能读取文件行内容;END读完所有行,只能访问汇总变量,不能访问$1等行字段。
6.变量:awk 内部变量 ** 不要加 $**,`sum +=$2;$sum` 会错误解析字段。
# 错误awk '{ $sum += $2 } END {print $sum}'# 正确awk '{ sum += $2 } END {print sum}'
7.空行:空行 NF=0,可以用awk 'NF>0' file过滤空行。
实战经验:日志提取字段、统计 PV、求和计数;awk 'NF>0'过滤空行非常好用。
三剑客组合实战案例(生产常用)
案例 1:Nginx 日志,统计访问状态码 200 的 IP
# access.log示例:ip - - [time] "req" 200 ...grep ' 200 ' access.log | awk '{print $1}' | sort | uniq -c
案例 2:清理配置,去掉注释空行,替换参数
sed -i.bak '/^#/d;/^$/d' app.confsed -i 's#old_path#/data/new#g' app.conf
案例 3:过滤错误日志,提取时间与接口
cat app.log | grep -i ERROR | awk '{print $1,$2,$7}'案例 4:找出磁盘使用率大于 80% 的分区
df -h | awk 'NR>1 {gsub(/%/,"",$5); if($5>80) print $0}'快速记忆总结
grep:找行,擅长搜索过滤;坑:正则特殊字符、-c是行数不是字符串数。
sed:改行,替换删除插入;坑:不加 - i 不改原文件,忘记 g 只替换第一个,mac 与 linux sed 差异。
awk:拆列 + 统计,小编程语言;坑:单引号、变量不加 $,分隔符是正则,BEGIN/END 逻辑。
选型经验:
只想搜找行 → grep
需要对整行增删替换 → sed
需要切割列、算数、汇总统计 → awk
