工具 | 主要用途 | 适合场景 | 语法复杂度 |
---|---|---|---|
grep | 搜索/过滤 | 快速查找 | 低 |
sed | 替换/编辑 | 批量修改 | 中 |
awk | 分析/格式化 | 统计与报表 | 高 |
grep "pattern" file.txt
-i
:忽略大小写-v
:反向匹配(不包含模式的行)-n
:显示行号-r
:递归搜索目录-E
:支持扩展正则-A N
:显示匹配行后N行-B N
:显示匹配行前N行-C N
:显示匹配行前后N行grep -E "^\d{3}-\d{2}-\d{4}$" data.txt # 匹配SSN格式
grep -E "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" mail.txt # 匹配邮箱
.
、*
、?
等。grep "error" /var/log/syslog # 搜索包含error的行
grep -i "warning" *.log # 忽略大小写
grep -v "^#" config.conf # 显示非注释行
grep -n "main" *.c # 显示行号
grep -r "TODO" src/ # 递归搜索目录
grep -E "(error|fail)" app.log # 多模式匹配
grep -A 2 -B 1 "exception" app.log # 显示上下文
sed 's/old/new/' file.txt
-n
:静默模式(只输出被处理的行)-e
:多条编辑命令-i
:直接修改原文件(慎用)-r
:支持扩展正则-f
:从文件读取命令sed -E 's/(\d{4})-(\d{2})-(\d{2})/\3\/\2\/\1/g' date.txt # 日期格式转换
echo -e "a\nb\nc" | sed -n '1,2p' # 打印第1-2行
sed '/pattern1/,/pattern2/d' file.txt # 删除两模式之间的内容
-i
参数会直接覆盖原文件,建议先备份。#
等避免与路径冲突:sed 's#/usr/bin#/bin#g'
sed 's/foo/bar/g' file.txt # 全文替换foo为bar
sed -i 's/localhost/127.0.0.1/g' conf.ini # 原地替换
sed -n '/error/p' app.log # 只输出包含error的行
sed '/^#/d' config.conf # 删除注释行
sed '2,5d' file.txt # 删除第2到5行
sed '1i\# 新增一行' file.txt # 在首行前插入内容
sed 's/[0-9]\{3\}/***&***/g' data.txt # 匹配三位数字加标记
awk '{print $1}' file.txt
-F
:指定分隔符(默认空格)NR
:当前记录号(行号)NF
:当前行字段数BEGIN
/END
:处理前/后执行awk 'BEGIN{FS=","; print "Name,Score"} {sum+=$2} END{print "Total:",sum}' data.csv
awk '{for(i=1;i<=NF;i++) a[$i]++} END{for(k in a) print k,a[k]}' file.txt # 统计单词频率
awk 'length($0)>80' file.txt # 打印超过80字符的行
FS
:输入字段分隔符OFS
:输出字段分隔符RS
:输入记录分隔符ORS
:输出记录分隔符FNR
:当前文件的记录数ARGC
/ARGV
:参数个数/数组awk '{arr[$1]+=$2} END{for(k in arr) print k,arr[k]}' data.txt # 按第一列分组求和
awk 'function square(x){return x*x} {print $1,square($2)}' data.txt
-F ','
。$1
、$2
,不要漏写$
。awk -F ':' '{print $1,$3}' /etc/passwd # 取用户名和UID
awk '{sum+=$2} END {print sum}' data.txt # 求第2列和
awk '$3>80 {print $1,$3}' score.txt # 条件筛选
awk 'NR==1,NR==5 {print $0}' file.txt # 打印1-5行
awk 'BEGIN{print "Name Score"} {print $1,$2}' score.txt # 加表头
awk -F ',' '{printf "%-10s %5.2f\n", $1, $2}' data.csv # 格式化输出
功能 | grep | sed | awk |
---|---|---|---|
搜索 | ✅ | ✅(/pattern/p) | ✅($0~//) |
替换 | ❌ | ✅ | ✅(gsub/sub) |
删除 | ❌ | ✅ | ✅(条件不打印) |
统计/汇总 | ❌ | ❌ | ✅ |
格式化输出 | ❌ | ❌ | ✅ |
多行处理 | 部分支持 | 支持 | 支持 |
易混辨析:
- grep适合查找,sed适合批量替换,awk适合分析和格式化。
- sed和awk都能做替换,但awk更适合复杂逻辑。
grep -c "error" app.log
awk '/error/ {count++} END {print count}' app.log
sed -i 's/192.168.1.1/10.0.0.1/g' *.conf
du -ah | sort -hr | head -10
awk -F ',' '{printf "%s\t%s\n", $1, $3}' data.csv
sed '/^$/d;/^#/d' file.txt
Q: grep、sed、awk三者的主要区别和适用场景?
A: grep用于查找和过滤,sed用于批量编辑和替换,awk用于分析、统计和格式化输出。
Q: 如何用awk统计某列的平均值?
A:
awk '{sum+=$2} END {print sum/NR}' file.txt
Q: sed如何只替换每行第一个匹配?
A: 默认只替换第一个,
s/old/new/
。
Q: grep如何递归搜索并显示行号?
A:
grep -rn pattern dir/
cat file | grep ... | sed ... | awk ...
LC_ALL=C
提升速度rg
(ripgrep)等现代工具提升效率-f
参数独立维护,便于复用cat app.log | grep 'ERROR' | sed 's/ERROR/ERR/g' | awk '{count++} END{print "总错误行数:",count}'
cat data.csv | grep -v '^#' | sed '/^$/d' | awk -F ',' '{if($3>80) print $1,$3}'
find . -name '*.log' | xargs grep 'timeout' | awk -F ':' '{print $1}' | sort | uniq -c | sort -nr
总结:
Linux文本处理三剑客各有专长,合理组合可高效完成日志分析、批量替换、数据统计等任务。多练习、多组合,成为文本处理高手!