前言
Linux 下一切皆文件,而日志、配置、命令输出全是文本。grep 找、sed 改、awk 算——这三把剑练熟,日常 80% 的文本处理需求都能搞定。
一、grep:文本搜索
# 基本搜索(支持管道)
grep "ERROR" app.log
journalctl -u nginx | grep -i "fail" # -i 忽略大小写
# 常用选项
grep -n "root" /etc/passwd # 显示行号
grep -c "ERROR" app.log # 只统计匹配行数
grep -v "127.0.0.1" access.log # 反向: 排除匹配的行
grep -r "bind 0.0.0.0" /etc/ # 递归搜目录
grep -E "ERROR|FATAL" app.log # 扩展正则, 多模式
grep -A 3 -B 1 "panic" app.log # 显示匹配行的后3行、前1行
grep -w "error" app.log # 全词匹配
基础正则速查:
| 符号 | 含义 | 示例 |
|---|---|---|
^ |
行首 | grep "^#" 注释行 |
$ |
行尾 | grep ":$" 以冒号结尾 |
. |
任意单字符 | grep "r.ot" |
* |
前一字符 0+ 次 | grep "go*gle" |
[] |
字符集合 | grep "^[abc]" |
[^] |
取反 | grep "^[^#]" 非注释行 |
实战:统计 Nginx 日志里出现最多的 10 个 IP:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head
二、sed:流编辑器
sed 逐行读取文本,对每行执行编辑命令后输出。核心场景是替换。
# 替换每行第一个匹配
sed 's/http/https/' conf.txt
# 替换所有匹配(全局 g 标志)
sed 's/http/https/g' conf.txt
# 直接修改文件(-i), 先备份为 .bak
sed -i.bak 's/8080/9090/g' app.conf
# 只处理第 2~5 行
sed '2,5s/8080/9090/g' app.conf
# 删除注释行和空行
sed -e '/^#/d' -e '/^$/d' sshd_config
# 删除第 3 行
sed '3d' file.txt
# 在第 2 行后插入一行
sed '2a ServerName antidebug.cn' httpd.conf
# 打印 10~20 行(当 sed 用)
sed -n '10,20p' big.log
⚠️ 生产环境改配置前,先
sed预览输出,确认无误后再加-i;重要文件务必-i.bak留备份。
三、awk:文本计算器
awk 按**字段(列)**处理文本,默认以空格/Tab 分隔,$1 是第一列,$0 是整行。
# 打印第 1、3 列
awk '{print $1, $3}' data.txt
# 指定分隔符
awk -F: '{print $1, $7}' /etc/passwd
# 条件过滤: 磁盘使用率超过 80% 的分区
df -h | awk '$5+0 > 80 {print $6, $5}'
# 内置变量
awk -F: '{print NR": "$1}' /etc/passwd # NR 当前行号
awk '{print NF}' file # NF 当前行字段数
# 使用分隔符美化输出
awk -F: -v OFS=' | ' '{print $1, $3, $7}' /etc/passwd
BEGIN / END 块做统计
# 统计第 1 列的总和与平均值
awk 'BEGIN {sum=0} {sum+=$1} END {print "sum="sum, "avg="sum/NR}' nums.txt
# 统计每种 HTTP 状态码出现次数
awk '{count[$9]++} END {for (s in count) print s, count[s]}' access.log
从日志里提取信息
# 提取 500 错误的 URI(第 9 列是状态码)
awk '$9 == 500 {print $7}' access.log | sort | uniq -c | sort -rn
# 提取响应时间超过 1s 的请求(假设 $NF 是耗时)
awk '$NF > 1.0 {print $4, $7, $NF}' access.log | head
四、三剑合璧:一条经典流水线
统计访问日志中 昨天 每小时 PV,并输出 Top 时段:
grep "$(date -d yesterday '+%d/%b/%Y')" access.log \
| awk '{print substr($4,14,2)}' \
| sort | uniq -c \
| sort -rn | head -5
每一环的分工:
grep → 框定目标行(按日期)
awk → 抽取小时字段
sort → 排序(uniq 统计前必须先排序)
uniq -c → 相邻去重并计数
sort -rn → 按数字倒序取 Top
五、速查表
| 需求 | 命令 |
|---|---|
| 找匹配行及上下文 | grep -A3 -B1 "err" log |
| 全局替换并备份 | sed -i.bak 's/a/b/g' f |
| 删除注释和空行 | sed -e '/^#/d' -e '/^$/d' f |
| 打印某列 | awk '{print $3}' f |
| 按条件过滤行 | awk '$3 > 100' f |
| 分组计数 | awk '{c[$1]++} END{for(k in c) print k,c[k]}' |
| Top N | sort | uniq -c | sort -rn | head |
小结
三剑客的价值在于组合:管道把简单工具串成流水线,每一步只做一件事。日志分析、配置批量修改、数据提取统计,都离不开它们。建议把本文几个实战命令在自己的机器上敲一遍,肌肉记忆比收藏有用。
本文是「Linux 基础」系列第 3 篇,下篇预告:Linux 进程管理。