摘要:在 Linux 运维领域,文本处理三剑客 grep、sed、awk 是命令行操作的核心。但若想构建完整的文本处理流水线,还需掌握 cut、sort、uniq 和 wc 等辅助工具。本文将详细分解这些工具如何协同工作,助你彻底掌握文本处理高阶技巧,筑牢自动化运维的基石。
文章目录
一、cut命令:精准切割文本列
核心功能:按指定分隔符切割文本列,提取关键字段
语法结构:cut -d’分隔符’ -f列号 文件
1.1 日志分析
日志格式:
# access.log
192.168.106.100 - - [24/Apr/2025:13:46:16 +0000] "GET /api/project/sysArea/tree HTTP/1.1" 200 147
192.168.106.100 - - [24/Apr/2025:13:46:18 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 200 2307
# data.csv
ID,Name,Email,Phone
1,John Doe,john@example.com,123-456-7890
2,Jane Smith,jane@example.com,987-654-3210
# text.txt
Line1: abc123def456
Line2: randomtext987654
Line3: 1234numbers5678words
实战案例:
# 提取Nginx访问日志中的IP列(默认空格分隔)
cut -d' ' -f1 access.log
# 输出
192.168.106.100
192.168.106.100
# 处理CSV文件(逗号分隔),提取第2和第4列
cut -d',' -f2,4 data.csv
# 输出
Name,Phone
John Doe,123-456-7890
Jane Smith,987-654-3210
# 高级技巧:
# 反向匹配:--complement 提取指定列外的所有内容
# 提取除第2列外的所有信息
cut -d',' -f2 --complement data.csv
# 输出
ID,Email,Phone
1,john@example.com,123-456-7890
2,jane@example.com,987-654-3210
# 字符范围切割:-c参数按字符位置提取
# 提取每行第5-8个字符
cut -c5-8 text.txt
# 输出
1: a
2: r
3: 1
1.2 性能对比:处理简单日志文件时,cut与awk哪个更快?
# 当文件为66M时,输出如下
正在测试 cut...
正在测试 awk...
--------------------------------
最终结果:
cut 耗时:总耗时:1.27 秒
awk 耗时:总耗时:5.65 秒
# 当文件为753M时,输出如下:
正在测试 cut...
正在测试 awk...
--------------------------------
最终结果:
cut 耗时:总耗时:13.19 秒
awk 耗时:总耗时:57.53 秒
# 结论:简单日志场景下,cut比awk快3倍多,合理选择工具是提高效率的关键。
二、sort+uniq 组合:排序与去重神器
核心功能:sort排序 + uniq去重
日志格式:
192.168.106.100 - - [24/Apr/2025:13:46:16 +0000] "GET /api/project/sysArea/tree HTTP/1.1" 200 147
192.168.106.100 - - [24/Apr/2025:13:46:18 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 200 2307
192.168.106.200 - - [24/Apr/2025:13:46:18 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 200 2307
实战案例:访问频次统计,查找异常IP
# 提取IP列后排序去重
cut -d' ' -f1 access.log | sort | uniq
# 输出
192.168.106.100
192.168.106.200
# 统计每个IP的访问次数,并按次数的降序排序
cut -d' ' -f1 access.log | sort | uniq -c | sort -nr
# 输出:
2 192.168.106.100
1 192.168.106.200
# 参数详解:
sort -n:数值排序
sort -r:降序
sort -k3:按第3列排序
uniq -c:统计重复次数
sort -u:直接输出唯一值(等效于uniq)
三、wc命令:文本统计利器
核心功能:统计行数、字数、字符数,快速校验文件
实战案例:日志和代码审计
# 统计总行数(审计配置文件)
wc -l config.conf
# 输出:
87 config.conf
# 统计单词数(分析安全日志)
wc -w security.log
# 输出:
260 security.log
# 统计字节数(检查日志文件大小)
wc -c debug.log
# 输出:
2653 debug.log
# 组合技巧:
# 管道统计:ls | wc -l统计当前目录文件数
# 输出:
16
# 代码量统计:
find . -name "*.py" | xargs wc -l统计Python代码总量
# 输出:
35 ./generate_logs.py
35 ./generate_logs_bak.py
70 总用量
# 可视化扩展:结合watch命令实时监控日志增长
# 每5秒刷新一次,相当于每五秒执行一次:cat access.log | wc -l
watch -n 5 'wc -l access.log'
# 输出:
Every 5.0s: wc -l access.log Fri Apr 25 01:59:37 2025
230671 access.log
四、协同作战:构建处理流水线
4.1 grep + cut + sort + uniq:日志分析流水线
日志格式:
# app.log
2023-01-01 12:00:00 ERROR: Database connection failed
2023-01-01 12:00:00 ERROR: Database connection failed
2023-01-01 12:01:00 INFO: User login successful
2023-01-01 12:02:00 ERROR: File not found
2023-01-01 12:03:00 WARNING: Disk space low
2023-01-01 12:04:00 ERROR: Database connection failed
2023-01-01 12:04:00 ERROR: Database connection failed
2023-01-01 12:05:00 ERROR: File not found
2023-01-01 12:06:00 ERROR: Network timeout
2023-01-01 12:07:00 INFO: Backup completed
2023-01-01 12:08:00 ERROR: Network timeout
2023-01-01 12:09:00 ERROR: Database connection failed
#
# 完整流程:提取错误日志→去重并统计重复次数→按照重复次数降序排列→取重复次数最多的10次错误
grep "ERROR" app.log | uniq -c | sort -nr | head -n 10
# 输出:
2 2023-01-01 12:04:00 ERROR: Database connection failed
2 2023-01-01 12:00:00 ERROR: Database connection failed
1 2023-01-01 12:09:00 ERROR: Database connection failed
1 2023-01-01 12:08:00 ERROR: Network timeout
1 2023-01-01 12:06:00 ERROR: Network timeout
1 2023-01-01 12:05:00 ERROR: File not found
1 2023-01-01 12:02:00 ERROR: File not found
4.2 sed + awk + wc:配置合规性检查
# 检查密码文件权限设置
sed -n '/password/p' /etc/security/pwquality.conf |
awk '{print $2}' |
grep -v "^#" |
wc -l
# 输出:
15
4.3 嵌套使用:复杂数据处理
# 统计每个用户的登录次数(处理last输出)
last |
awk '{print $1}' |
sort |
uniq -c |
awk '{print $2, $1}' |
sort -k2 -nr
# 输出:
root 14
reboot 4
wtmp 1
1
五、实战案例
5.1 服务器健康检查
# 检查磁盘使用率(超过10%报警)
df -h |
awk '+$5 > 10 {print $6}' |
cut -d'%' -f1 |
xargs -I{} echo "磁盘 {} 使用率过高"
# 输出:
磁盘 / 使用率过高
磁盘 /boot 使用率过高
5.2 网络流量分析
# 提取流量TOP10的IP
iftop -t -s 2 -n |
awk '{print $2}' |
cut -d':' -f1 |
sort |
uniq -c |
sort -nr |
head -n 10
# 输出:
interface: ens33
IP address is: 192.168.188.138
MAC address is: 00:0c:29:38:50:41
5
2 send
1 (sent/received/total)
1 receive
1 rate
1 on
1 Host
1 192.168.188.138
1 <=
5.3 代码质量检查
# 统计代码重复率(使用pmd工具)
pmd check -d src/ |
grep "重复代码" |
wc -l
5.4 安全审计
日志格式:
Jan 1 10:00:00 Linux02 sshd[1234]: Failed password for invalid user testuser from 192.168.1.1 port 22
Jan 1 10:01:00 Linux02 sshd[1235]: Failed password for invalid user admin from 192.168.1.1 port 22
Jan 1 10:02:00 Linux02 sshd[1236]: Failed password for invalid user root from 192.168.1.1 port 22
Jan 1 10:03:00 Linux02 sshd[1237]: Failed password for invalid user guest from 192.168.1.1 port 22
Jan 1 10:04:00 Linux02 sshd[1238]: Failed password for invalid user test from 192.168.1.1 port 22
Jan 1 10:05:00 Linux02 sshd[1239]: Failed password for invalid user user from 192.168.1.1 port 22
Jan 1 10:06:00 Linux02 sshd[1240]: Failed password for invalid user demo from 192.168.1.2 port 22
Jan 1 10:07:00 Linux02 sshd[1241]: Failed password for invalid user backup from 192.168.1.2 port 22
Jan 1 10:08:00 Linux02 sshd[1242]: Failed password for invalid user oracle from 192.168.1.2 port 22
Jan 1 10:09:00 Linux02 sshd[1243]: Failed password for invalid user mysql from 192.168.1.2 port 22
# 检测SSH暴力破解尝试
grep "Failed password" /var/log/auth.log |
awk '{print $13}' |
sort |
uniq -c |
awk '$1 > 5 {print "IP "$2" 有 "$1" 次失败尝试"}'
# 输出:
IP 192.168.1.1 有 6 次失败尝试
六、性能对比与优化建议
工具 | 处理10万行数据耗时 | 内存占用 | 适用场景 |
---|---|---|---|
cut | 0.12s | 5MB | 快速列提取 |
sort | 0.85s | 50MB | 排序操作 |
uniq | 0.34s | 10MB | 去重统计 |
wc | 0.05s | 2MB | 基础统计 |
优化策略:
- 大文件处理时,优先使用 sort -S 指定内存
- 需要保留原始顺序时,使用 sort -s 稳定排序
- 复杂模式匹配时,grep -F 比正则快3倍
- 多核CPU环境,sort --parallel=4 加速排序
七、可视化工具集成
日志格式:
192.168.106.168 - - [24/Apr/2025:21:09:19 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 200 691
192.168.106.273 - - [24/Apr/2025:02:17:06 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 404 4695
192.168.106.241 - - [24/Apr/2025:15:45:33 +0000] "GET /api/project/sysArea/tree HTTP/1.1" 404 3823
192.168.106.289 - - [24/Apr/2025:10:22:12 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 404 2738
192.168.106.283 - - [24/Apr/2025:16:42:58 +0000] "GET /api/project/sysArea/tree HTTP/1.1" 200 3906
192.168.106.243 - - [24/Apr/2025:02:43:32 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 404 3567
192.168.106.273 - - [24/Apr/2025:02:45:44 +0000] "GET /api/project/sysArea/tree HTTP/1.1" 404 2482
192.168.106.241 - - [24/Apr/2025:23:27:34 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 200 244
192.168.106.108 - - [24/Apr/2025:08:40:29 +0000] "GET /assets/index.D0ZTK57s.js HTTP/1.1" 200 3200
192.168.106.283 - - [24/Apr/2025:00:05:18 +0000] "GET /api/project/sysArea/tree HTTP/1.1" 404 3471
# 统计IP及重复次数
cut -d' ' -f1 access.log |
sort |
uniq -c |
sort -r |
awk '{print $2","$1}' > traffic.csv
# 输出:
192.168.106.283,2
192.168.106.273,2
192.168.106.241,2
192.168.106.289,1
192.168.106.243,1
192.168.106.168,1
192.168.106.108,1
# 使用Grafana可视化:
# 生成时间序列数据
awk '{print $4","$1}' access.log |
sort -k1 |
uniq -c |
awk '{print $2","$1","$3}' > time_series.csv
# 输出:
[24/Apr/2025:00:05:18,192.168.106.283,1,
[24/Apr/2025:02:17:06,192.168.106.273,1,
[24/Apr/2025:02:43:32,192.168.106.243,1,
[24/Apr/2025:02:45:44,192.168.106.273,1,
[24/Apr/2025:08:40:29,192.168.106.108,1,
[24/Apr/2025:10:22:12,192.168.106.289,1,
[24/Apr/2025:15:45:33,192.168.106.241,1,
[24/Apr/2025:16:42:58,192.168.106.283,1,
[24/Apr/2025:21:09:19,192.168.106.168,1,
[24/Apr/2025:23:27:34,192.168.106.241,1,
# 自动化报告生成:
bash
# 生成HTML报告
echo "<table>" > report.html
awk '{print "<tr><td>"$1"</td><td>"$2"</td></tr>"}' time_series.csv >> report.html
echo "</table>" >> report.html
# 输出:
<table>
<tr><td>[24/Apr/2025:00:05:18,192.168.106.283,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:02:17:06,192.168.106.273,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:02:43:32,192.168.106.243,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:02:45:44,192.168.106.273,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:08:40:29,192.168.106.108,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:10:22:12,192.168.106.289,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:15:45:33,192.168.106.241,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:16:42:58,192.168.106.283,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:21:09:19,192.168.106.168,1,</td><td></td></tr>
<tr><td>[24/Apr/2025:23:27:34,192.168.106.241,1,</td><td></td></tr>
</table>
八、安全注意事项
- 处理敏感数据时,使用 cut 后务必清理临时文件
- 避免直接修改生产环境文件,优先使用 sed -i.bak 创建备份
- 复杂脚本执行前,先用 echo 命令验证管道输出
- 对未知文件使用 wc -c 检查大小,防止内存溢出
九、学习路径建议
- 基础阶段:掌握 cut/sort/uniq/wc 基础语法
- 进阶阶段:学习三剑客组合使用
- 实战阶段:分析真实日志(如/var/log/syslog)
- 优化阶段:研究工具参数对性能的影响
- 扩展阶段:探索 jq 处理JSON、csvkit处理CSV
十、结语
通过本文的详细解析和实战案例,读者可构建完整的文本处理工具链,实现从基础日志分析到复杂数据处理的全面能力升级。
如果你觉得这篇文章对你有帮助,不妨点个赞👍,或者分享给你的朋友们吧!你的支持是我持续创作的最大动力!