在Linux环境下,我们经常需要处理各种复杂的文本任务:日志分析、数据提取、格式转换、批量修改等等。之前分享了三剑客每个使用方法;但是实际工作中问题会更加复杂,今天将为大家分享如何将grep、sed、awk这"三剑客"组合使用,解决一些实际工作中遇到的复杂场景问题。一、三剑客简介
在深入实战之前,我们先简单回顾一下三剑客的核心功能:
- grep:文本搜索工具,擅长查找匹配特定模式的行
- sed:流编辑器,擅长对文本进行编辑(增删改查)
- awk:文本处理工具,擅长对列进行复杂处理和格式化输出
二、实战场景一:复杂日志分析与统计
场景描述
分析Nginx访问日志,统计每个IP的访问次数、访问最多的URL以及状态码分布情况。
解决方案
| # 1. 统计每个IP的访问次数 |
| grep -v "192.168.1.1" access.log | \ |
| awk '{print $1}' | sort | uniq -c | sort -nr > ip_access_count.txt |
| |
| # 2. 提取访问最多的URL(排除静态资源) |
| grep -vE "\.(jpg|png|css|js)" access.log | \ |
| awk '{print $7}' | sort | uniq -c | sort -nr | head -10 > top_urls.txt |
| |
| # 3. 分析状态码分布 |
| awk '{print $9}' access.log | sort | uniq -c | sort -nr > status_code_dist.txt |
| |
| # 4. 组合统计:IP访问次数、状态码分布和访问最多的URL |
| echo "=== IP访问次数TOP5 ===" && \ |
| grep -v "192.168.1.1" access.log | \ |
| awk '{print $1}' | sort | uniq -c | sort -nr | head -5 |
| |
| echo -e "\n=== 状态码分布 ===" && \ |
| awk '{print $9}' access.log | sort | uniq -c | sort -nr |
| |
| echo -e "\n=== 访问最多的URL ===" && \ |
| grep -vE "\.(jpg|png|css|js)" access.log | \ |
| awk '{print $7}' | sort | uniq -c | sort -nr | head -5 |
技巧解析
- 利用
awk提取关键列($1为IP,$7为URL,$9为状态码) - 通过
sort | uniq -c | sort -nr实现计数和排序
三、实战场景二:CSV数据清洗与转换
场景描述
处理一个包含用户信息的CSV文件,需要:
解决方案
| # 1. 删除无效邮箱行(邮箱不包含@或.) |
| grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" users.csv > valid_users.csv |
| |
| # 2. 手机号格式化(统一为138-XXXX-XXXX格式) |
| sed -E 's/([0-9]{3})([0-9]{4})([0-9]{4})/\1-\2-\3/g' valid_users.csv > formatted_users.csv |
| |
| # 3. 计算用户年龄(假设生日在第3列) |
| awk -F',''BEGIN{OFS=","} {$4=2023-$4; print}' formatted_users.csv > users_with_age.csv |
| |
| # 4. 提取技术部门用户并导出 |
| grep "技术部" users_with_age.csv > tech_users.csv |
| |
| # 5. 组合命令:一步完成所有操作 |
| grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" users.csv | \ |
| sed -E 's/([0-9]{3})([0-9]{4})([0-9]{4})/\1-\2-\3/g' | \ |
| awk -F',''BEGIN{OFS=","} {$4=2023-$4; print}' | \ |
| grep "技术部" > final_tech_users.csv |
技巧解析
awk 中设置字段分隔符-F','和输出分隔符OFS=","
四、实战场景三:配置文件批量修改
场景描述
批量修改Nginx配置文件中的:
解决方案
| # 1. 修改端口(将listen 80改为listen 8080) |
| sed -i 's/listen 80;/listen 8080;/g' nginx.conf |
| |
| |
| sed -i '/^}/i\ # Custom configuration\n location /custom {\n return 200 "Custom response";\n }\n' nginx.conf |
| |
| |
| sed -i '/^#/d' nginx.conf |
| |
| |
| |
| s/listen 80;/listen 8080;/g; |
| |
| |
| |
| return 200 "Custom response";\ |
| |
| |
| |
| |
| |
| grep -n "listen 8080" nginx.conf |
| grep -A5 "location /custom" nginx.conf |
技巧解析
五、实战场景四:系统性能日志分析
场景描述
分析系统性能日志,找出:
解决方案
| # 1. 提取CPU使用率超过80%的记录 |
| grep -E "CPU: [8-9][0-9]%" performance.log > high_cpu_usage.log |
| |
| # 2. 提取内存使用信息并找出前5个高内存进程 |
| grep "Memory:" performance.log | \ |
| awk '{print $3, $5}' | sort -k2 -nr | head -5 > top_memory_processes.txt |
| |
| # 3. 分析磁盘IO繁忙时间段 |
| grep "Disk IO:" performance.log | \ |
| awk '{print $4, $6}' | sort -k2 -nr | head -5 > busy_disk_io_periods.txt |
| |
| # 4. 组合分析:生成性能报告 |
| echo "=== 高CPU使用率时间点 ===" && \ |
| grep -E "CPU: [8-9][0-9]%" performance.log | \ |
| |
| |
| echo -e "\n=== 内存使用最高的5个进程 ===" && \ |
| grep "Memory:" performance.log | \ |
| awk '{print $3, $5}' | sort -k2 -nr | head -5 |
| |
| echo -e "\n=== 磁盘IO最繁忙的5个时间段 ===" && \ |
| grep "Disk IO:" performance.log | \ |
| awk '{print $4, $6}' | sort -k2 -nr | head -5 |
技巧解析
六、三剑客组合使用的高级技巧
1. 使用awk处理多行记录
| # 处理多行日志(例如堆栈跟踪) |
| awk '/Exception in thread/,/at /' logfile.txt |
2. 结合正则表达式进行复杂匹配
| # 匹配包含特定IP且状态码为500的日志 |
| grep -E "192\.168\.1\.[0-9]+.* 500" access.log |
3. 使用sed进行条件替换
| # 只替换匹配特定模式的行 |
| sed '/^server_name /s/example.com/newdomain.com/' nginx.conf |
4. awk中处理数组
| # 统计每个状态码出现的次数 |
| awk '{count[$9]++} END {for (code in count) print code, count[code]}' access.log |
5. 三剑客组合的黄金法则
- grep 用于初步筛选和过滤
- sed 用于行内修改和替换
- awk 用于列处理和复杂计算
七、总结
Linux三剑客组合使用是运维人员必备的技能,通过灵活组合grep、sed、awk,我们可以高效解决各种复杂的文本处理任务:
- grep 负责筛选和定位
- sed 负责编辑和修改
- awk 负责处理和格式化
在实际工作中,多尝试将这三个工具组合使用,你会发现很多复杂的任务都能用简洁的命令组合完成。记住,掌握三剑客组合使用的关键在于理解每个工具的特点,并根据任务需求选择合适的工具和组合方式。