linux-sre-handbook

02-文本处理三剑客

grep — 文本搜索

# 基本用法
grep "pattern" file                # 搜索匹配行
grep -v "pattern" file             # 反选
grep -i "pattern" file             # 忽略大小写
grep -r "pattern" /path/           # 递归搜索
grep -n "pattern" file             # 显示行号
grep -c "pattern" file             # 计数
grep -A 3 "pattern" file           # 匹配行后 3 行
grep -B 2 "pattern" file           # 前 2 行
grep -C 3 "pattern" file           # 前后各 3 行

# 正则 (ERE 用 -E 或 egrep)
grep -E "error|fail" app.log       # 或
grep -E "^2025" app.log            # 锚定行首
grep -E "pid=\d+" app.log          # 数字
grep -P "(?<=status=)\d+" file     # PCRE 后顾断言

sed — 流编辑器

# 替换 (s/pattern/replacement/flags)
sed 's/foo/bar/' file              # 每行首次替换
sed 's/foo/bar/g' file             # 全局替换
sed 's/foo/bar/2' file             # 每行第 2 次替换
sed -i 's/foo/bar/g' file          # 原地修改

# 条件选择
sed -n '5p' file                   # 打印第 5 行
sed -n '5,10p' file                # 打印 5-10 行
sed '/pattern/d' file              # 删除匹配行
sed '/start/,/end/d' file          # 删除区间

# 插入/追加
sed '1i\header line' file          # 第 1 行前插入
sed '$a\footer line' file          # 末尾追加

# 多行模式
sed '/start/,/end/s/foo/bar/g' file

# 常用实战
sed -i 's/\r$//' file              # 移除 Windows 换行
sed -i '/^$/d' file                # 删除空行
sed 's/^[ \t]*//;s/[ \t]*$//' file # 去除首尾空白

awk — 文本分析语言

# 基本结构
awk 'pattern { action }' file

# 字段处理
awk '{print $1}' file              # 第 1 列
awk '{print $NF}' file             # 最后一列
awk -F: '{print $1,$3}' /etc/passwd  # 自定义分隔符
awk -F, '{print NF}' file          # 列数

# 条件过滤
awk '$3 > 100 {print $1}' file     # 数值比较
awk '/error/ || /fail/' file       # 正则匹配
awk 'NR>=5 && NR<=10' file         # 行号范围

# 内置变量
NR    # 当前行号
FNR   # 当前文件内行号
NF    # 当前行字段数
FILENAME
OFS   # 输出分隔符
RS    # 记录分隔符

# 计算
awk '{sum+=$1} END {print sum}' file
awk '{avg+=$1} END {print avg/NR}' file

# 关联数组
awk '{count[$1]++} END {for(k in count) print k,count[k]}' file

组合实战 — 管道哲学

# 统计访问量 Top 10 IP
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

# 提取日志中 500 错误的请求路径
grep ' 500 ' app.log | awk '{print $7}' | sort | uniq -c | sort -rn

# 实时监控慢请求
tail -f app.log | awk '$NF>1000 {print "SLOW:",$0}'

# 配置文件解析(去注释和空行)
grep -v '^\s*#' nginx.conf | sed '/^$/d'

延伸阅读