文本处理核心工具:grep、cut、sort、uniq、tr 的常用技巧
日志解析说白了就是跟文本打交道。HSM 日志动辄几万行,你要是不懂这几个小工具,光靠眼睛看,眼睛会瞎的。
我个人习惯把这四个工具当作管道里的积木——grep 负责筛选,cut 负责切字段,sort 和 uniq 负责排序去重,tr 负责清洗。它们单独用很弱,但组合起来威力巨大。我先一个个讲清楚,最后给你看一个真实案例。
grep:筛选你真正关心的行
grep 是日志分析里出场率最高的工具。它的核心逻辑就一句话:保留匹配模式的行。
常用选项速查
| 选项 | 作用 | 典型场景 |
|---|---|---|
-i | 忽略大小写 | 日志里 ERROR 和 error 混用 |
-v | 反向匹配,排除指定行 | 去掉注释行或调试信息 |
-E | 扩展正则,支持 | 等 | 同时匹配多个关键词 |
-c | 只统计行数,不输出内容 | 快速了解某类事件出现多少次 |
-A / -B / -C | 打印匹配行前后若干行 | 看异常发生时的上下文 |
我记得刚接手一个 HSM 项目时,日志里报错总是夹杂在大量成功记录里。用 grep -i -E "fail|error|timeout" 一下就抓住了所有异常,省了我半天时间。
grep -c 看看数量。如果结果是 0,就不用再花时间翻屏了。
grep $'\t' 才搞定。记住:永远确认你查找的模式跟实际字符一致。
cut:像手术刀一样切字段
grep 筛出行,cut 则从行里提取你想要的列。日志通常是固定分隔符格式(比如冒号、逗号、空格),用 cut 最方便。
常用用法:
-d指定分隔符,默认是 tab-f指定要取的字段编号,从 1 开始
# 假设日志格式:2025-01-15 14:30:00,INFO,User login success
cut -d',' -f2 log.txt # 提取第二个字段:INFO
cut -d',' -f1,3 log.txt # 提取第一和第三字段
但有个坑:如果某行分隔符数量不一致,cut 会只输出到实际存在的字段为止,不会报错。我建议先用 awk 处理更复杂的场景,单纯取固定列时 cut 足够。
sort + uniq:排序和去重的黄金组合
日志里经常要统计某类事件有多少种、出现频次。这俩工具通常连着用:先 sort 把相同内容排在一起,再 uniq 去重并计数。
sort 常用选项
| 选项 | 作用 | 示例 |
|---|---|---|
-n | 按数值排序 | 按时间戳排序 |
-r | 降序 | 排在最前面的是最大值 |
-k | 指定排序字段 | 按第二列排序 |
-t | 指定字段分隔符 | 与 cut 类似 |
uniq 常用选项
| 选项 | 作用 |
|---|---|
-c | 显示每行重复次数 |
-d | 只显示重复行 |
-u | 只显示唯一行 |
实战中我经常这样用:
# 统计各种日志级别出现的次数
grep -oP '\b(INFO|WARN|ERROR|DEBUG)\b' log.txt | sort | uniq -c | sort -rn
这个管道先提取所有日志级别关键词,排序后去重计数,最后按次数降序排列。最高频的日志类别一目了然。
tr:字符串清洗工
tr 能做小范围的字符转换、删除、压缩。日志里常见的场景:去掉文件中的 ^M 回车符、统一大小写、替换分隔符。
# 将日志中所有大写字母转小写
tr 'A-Z' 'a-z' < log.txt
# 删除所有数字
tr -d '0-9' < log.txt
# 压缩连续的空格为单个空格
tr -s ' ' < log.txt
注意:tr 只处理字符,不处理字符串。你想把 "ERROR" 替换成 "ER" 用 tr 不行,得用 sed。tr 适合做粗粒度清洗,比如把制表符换成逗号,方便后续用 cut 处理。
我记得有一次客户发来的日志里混着全角空格(Unicode 0xa0),导致字段切分总出错。用 tr '\240' ' ' 先把全角空格替换成普通空格,后面就顺畅了。这种小坑你不实际操作很难碰到。
组合实战:一分钟统计 HSM 错误分类
下面我用一个真实需求串起所有工具。假设日志格式如下:
2025-01-15 14:30:00 [WARN] HSM: slot 0 key operation timeout
2025-01-15 14:31:12 [ERROR] HSM: PIN verification failed
2025-01-15 14:32:05 [INFO] HSM: session established
2025-01-15 14:33:44 [ERROR] HSM: key not found in device
2025-01-15 14:34:01 [WARN] HSM: certificate expired
我想知道:每个错误类型出现了几次?
grep -oP '\[(WARN|ERROR)\].*' log.txt | # 只保留包含 WARN 或 ERROR 的行(其实 grep 可以换,这里演示 grep 筛选)
cut -d']' -f2 | # 取 ] 后面的内容
sed 's/^ *//' | # 去掉开头空格(sed 后续章节会讲,但这里备用)
sort | uniq -c | sort -rn # 统计频次,降序排列
输出:
1 key operation timeout
1 PIN verification failed
1 key not found in device
1 certificate expired
如果日志有上万行,这个管道几秒就出结果,手动做根本不可能。
知识体系:这些工具在管道中的协作逻辑
下面这张图能帮你理解它们怎么配合:
你看,每个工具负责一个环节,通过管道串起来后就能完成复杂的日志解析任务。记牢这个流程,以后遇到文本处理需求,先想想能用哪几个工具组合,而不是一上来就写 Python 脚本。