在日常工作中,经常要处理日志、CSV表格或者系统监控数据。比如你刚导出了一份用户访问记录的文本文件,想快速统计某个时间段的访问次数,又或者想筛选出特定IP的请求行。这时候,shell管道就是你的效率神器。
管道的本质:前一个命令的输出,后一个命令的输入
管道用 | 符号表示,它把左边命令的结果“喂”给右边的命令去继续加工。就像流水线上的工人,每人只负责一步,最终完成整件产品。
比如查看当前目录下最大的5个文件:
ls -la | sort -k5 -nr | head -6
这条命令中,ls -la 列出所有文件详情,sort -k5 -nr 按第5列(文件大小)逆序排列,head -6 取前6行(含标题行)。每一步都专注做一件事,组合起来却很强大。
结合 awk 处理表格类数据
很多日志或导出数据其实是“类表格”格式,用空格或制表符分隔。awk 就是处理这种数据的好手。
假设你有个 sales.txt,每行是日期、地区、销售额,用空格隔开:
2024-05-01 北京 12000
2024-05-01 上海 9800
2024-05-02 北京 13500
2024-05-02 上海 10200
想统计上海的总销售额,可以这样写:
cat sales.txt | grep 上海 | awk '{sum += $3} END {print sum}'
先用 grep 筛出包含“上海”的行,再交给 awk 把每行第三个字段累加,最后输出结果。
用 cut 提取固定列内容
有时候数据是固定宽度或分隔明确的,比如 /etc/passwd 文件用冒号分隔。想提取所有用户名,可以:
cut -d: -f1 /etc/passwd
如果配合管道统计用户名数量:
cut -d: -f1 /etc/passwd | wc -l
去重与排序:sort 和 uniq 的黄金搭档
处理日志时,常会遇到重复的IP或URL。快速去重:
cat access.log | awk '{print $1}' | sort | uniq
这里先用 awk 提取第一列(通常是IP),然后排序,最后去重。注意 uniq 要求数据已排序,否则无法正确去重。
如果还想看每个IP出现了多少次,加个 -c 参数:
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr
这样就能看到访问量最高的IP排在最前面。
小技巧:用 tee 同时保存中间结果
调试复杂管道时,可能想看看某一步的输出。可以用 tee 把数据“分叉”一份到文件:
cat data.csv | grep '2024' | tee temp_2024.txt | awk -F, '{s+=$2} END{print s}'
这样既能继续处理,又把筛选后的2024年数据存了下来,方便后续核对。
管道的魅力在于组合。每个命令像一块积木,单独不显眼,串起来却能解决实际问题。多练几次,你会发现处理文本比打开Excel还快。