前排声明:这篇文章不是某个比赛的赛后总结,也不是什么正经教程。是我自己在折腾 Linux 命令、围观各路大神花式玩管道之后,攒下来的一堆真实体会和可直接抄走的组合方案。如果你对 | 的认知还停留在“把 ls 的结果传给 grep 看一下”,那这篇内容应该能帮你打开一扇新世界的大门。
1. 管道不是学出来的,是玩出来的
我和管道的故事,起点特别朴素。刚工作那会儿,看同事敲了一行巨长的命令,把几十个日志文件里的报错信息统计成了一张表格,我当时整个人是懵的。那行命令里全是 |,像一条流水线,左边程序的输出直接变成了右边程序的输入,最后落成一个清清楚楚的结果。
后来我明白了,这就是 Linux 管道设计最迷人的地方:它把“复杂任务”拆成了“一个接一个的小工具”,每个工具只做一件事,但组合起来就能完成一个看起来需要写几百行代码才能搞定的任务。
所谓“Linux 命令创意组合大赛”,本质上就是在玩这种连接的艺术。它不考你背了多少命令参数,也不考你会不会写 C 代码,它考的是你能不能像搭乐高一样,用现有的命令零件拼出一个有趣、高效、出人意料的解决方案。
这类比赛在大学社团、企业内部技术分享、甚至一些线上社区里都很流行。形式通常是:给出一个具体任务(比如“统计系统里占用磁盘最大的 10 个文件”),要求你用尽量短的管道组合实现,或者反过来,给你一段丑陋的管道命令,让你拆解它到底在干什么。
我围观和参与这类活动最大的收获是:你不需要把 Linux 命令手册背完,但你必须理解管道背后那套“程序间协作”的思想。 一旦想通了,你会发现很多原本要写脚本才能解决的问题,一条命令就能解决,而且解决得更优雅、更稳定。
这篇文章我会从管道的基础原理讲起,然后一层一层往上叠,分享我在实际工作和比赛中用过、见过的一些创意组合,最后把最容易踩的坑和排查思路一起整理出来。适合谁看?如果你是刚接触 Linux 的运维、开发、学生,或者玩过命令但总觉得没玩明白的“半吊子”,这篇内容应该能让你的命令行效率上一个台阶。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 第一层修炼:管道基本功与三个必会姿势
2.1 管道到底是什么:一场精准的“传话游戏”
理解管道,不需要去啃操作系统教科书。你就想象一个情景:A 同事把一件事情的处理结果写在纸上,然后通过一个滑梯滑给 B 同事,B 处理完再滑给 C。这个过程里,每个人只负责自己那一步,中间不需要把纸折起来、装进信封、再拆开。
Linux 管道就是那个滑梯。它连接了两个进程:左边进程的标准输出(stdout)变成了右边进程的标准输入(stdin)。数据以一种极其简单的方式流动——从左到右,逐字节传递。
理论层面,管道是靠内核里的一个**环形缓冲区(pipe buffer)**实现的。默认情况下,这个缓冲区的大小在 Linux 上是 64KB(16 个内存页)。左边命令往里写,右边命令从里读,写满了就阻塞等读,读空了就阻塞等写。这种设计保证了数据流是同步的、有序的,不会出现数据错乱。
但这里有个关键点值得注意:管道本身不关心流经它的数据是什么格式。它传的是纯文本字节流。这就是为什么管道命令的威力高度依赖文本处理命令。你 cat 一个文件,输出的是文本;你 ls -l,输出的也是文本;你查日志,那更是文本。只要输出是文本,就能被管道右边的命令处理。
基于这个特性,我总结出管道组合的三个基本功,也可以叫三个“必会姿势”。
2.2 姿势一:过滤 —— 从一堆信息里捞出你真正关心的
最常见的管道用法就是过滤。经典中的经典是 grep。
bash复制# 从系统日志里找所有 sshd 相关的报错
journalctl -u sshd | grep -i error
# 找到所有监听中的 TCP 端口,排除掉 IPv6 那一堆干扰项
ss -tlnp | grep LISTEN | grep -v '::1'
这里有个小技巧很多人刚开始不知道:grep 默认是输出包含匹配关键词的整行,不是只输出匹配的那一小段。所以当你发现输出结果信息量太大时,可以继续往后接处理命令。
grep 的进阶用法是 grep -A、-B、-C 控制上下文行数。排查日志时,光看报错那行往往不够,得看报错前后的几行才有线索。
bash复制# 看 Nginx 错误日志里所有 connect() failed 警告,附带前后 5 行上下文
grep -n -B 5 -A 5 "connect() failed" /var/log/nginx/error.log | tail -n 50
但过滤不止 grep 一个工具。awk 也是一种过滤,它按列过滤;sed 也算一种过滤,它按行做替换和筛选。三者的关系我用一句话概括:grep 管行,awk 管列,sed 管替换。 遇到复杂需求,先想清楚是用哪个的“主场”。
2.3 姿势二:统计 —— 让数据自己说话
光过滤出来还不够,很多时候你得知道“有多少”。于是第二个必会姿势登场:统计。
最基础的组合是 wc -l 数行数:
bash复制# 当前目录下有多少个 .conf 文件
find . -name "*.conf" | wc -l
# Nginx 访问日志里有多少条 500 状态码的请求
grep " 500 " access.log | wc -l
但真正有威力的是 sort | uniq -c 组合。这个组合能做“分组计数”,是处理日志的一把瑞士军刀。
举个例子,你想知道访问日志里哪些 IP 访问次数最多:
bash复制# 提取 IP 列(假设 access log 第一列是 IP),排序、去重统计、按出现次数倒序
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -n 10
这行命令我几乎每周都要用。四个环节缺一不可:awk 提取列,sort 把相同 IP 排到一起,uniq -c 统计连续相同行的数量,最后再 sort -rn 按数字大的排前面。
这里有一个很隐蔽的坑:uniq 只能统计相邻的重复行。如果数据没经过 sort 预处理,uniq -c 的结果就是乱的。我第一次用这个组合时,结果硬是少了数据,排查了半天才发现是忘了排序。
bash复制# 错误示范:没排序直接 uniq,统计结果会不对
awk '{print $1}' access.log | uniq -c | sort -rn | head -n 10
2.4 姿势三:定位与切片 —— 在你需要的地方停下来
第三种基本姿势是定位和切片,常用的工具是 head、tail、grep -m、sed -n。
head 和 tail 大家都懂,但有一些细节值得单独拿出来说。
tail -f 是实时跟踪文件追加内容的经典命令。很多教程只告诉你它用于“看系统日志”,但它在管道组合里有个更关键的使用场景:实时处理流式数据。
bash复制# 实时监控 Nginx 日志,只要出现 500 或 404 状态码就打印出来
tail -f /var/log/nginx/access.log | grep -E " (500|404) "
这就是管道“魔法”的第一次显现:你以为管道只是用来处理静态文件,但它其实能处理无限持续的数据流。tail -f 一直在追加输出,grep 一直在过滤,左边的进程和右边的进程是同时运行的,不用等左边跑完。
grep -m 则适合只想看前几个匹配结果的场景,避免大文件全量扫描导致终端刷屏。比如:
bash复制# 只看配置文件里前 3 个 server_name 配置
grep -m 3 "server_name" nginx.conf
三个姿势介绍完了。光看可能觉得不过如此,别急,管道真正好玩的地方在于组合本身。下一节我要讲两个“放大器”——它们能让你的管道命令从入门级一跃成为生产力工具。
3. 第二层进阶:xargs 与 tee —— 管道里的两个放大器
3.1 xargs:把文本变成参数的神奇胶水
先说 xargs。它的存在价值是解决一个管道组合的“顽疾”:左边命令输出的文本,怎么作为参数传给右边命令?
直接管道传输的是标准输入,但很多命令比如 rm、cp、mkdir 根本不读标准输入,它们只认命令行参数。这时候 xargs 就是桥梁——它把管道传过来的文本流拆分成一个个单词,然后把这些单词作为参数,去执行后面的命令。
bash复制# 删除 /tmp 下面所有 .tmp 文件
find /tmp -name "*.tmp" | xargs rm -f
如果不用 xargs,你会怎么写?rm -f $(find /tmp -name "*.tmp")。这种写法在文件数量少的时候没问题,可一旦文件名里有空格,或者文件数量多到超过命令行长度的上限(ARG_MAX,一般是 2MB 左右),就会出各种莫名其妙的 bug。
xargs 比这稳健得多。它默认按空格和换行拆分,而且会分批执行命令,一批满了就开下一批,不会一次性把所有参数塞给命令。
不过要注意:xargs 的默认拆分规则会在文件名带空格时翻车。稳妥做法是配合 find -print0 和 xargs -0:
bash复制# 用空字符作为分隔符,完美兼容文件名含空格的情况
find /data -name "*.log" -print0 | xargs -0 rm -f
xargs 还有一个很实用的参数 -I,它可以把你想要插入参数的位置“钉”在一个占位符上。比如你要批量重命名文件:
bash复制# 把当前目录所有 .txt 文件加上 .bak 后缀
find . -name "*.txt" | xargs -I {} mv {} {}.bak
这个 {} 就是你定义的占位符,xargs 会每一次从输入里取一行,替换掉两个 {},分别执行命令。这种写法直观、可控,比裸用 xargs 后面接命令要清晰得多。
3.2 tee:数据分流器,让你既能看又能存
如果说 xargs 是管道里的“参数放大器”,那 tee 就是“分流放大器”。
tee 这个名字本身就是个水管工术语——T 型三通。它把标准输入的数据原样写一份到标准输出,另外又写一份到指定的文件里。于是你在管道中间某个环节,就能把中间结果“截流”一份保存下来,方便调试。
bash复制# 统计日志里 404 状态码数量,同时把提取出来的 404 请求原始行存到文件里
grep " 404 " access.log | tee 404_requests.txt | wc -l
执行完这两步,你既能在终端看到统计数据,又保留了一份中间数据文件。后续想深入分析这些 404 请求,可以直接操作 404_requests.txt,不用重新过滤一遍整个日志。
tee 在比赛里经常被用来“炫技”:一道题要求一命令搞定统计并把报表导出,tee 的存在就让你不用写第二个命令。
tee 还有一个不怎么为人知的用法——给 sudo 提权用:
bash复制# 直接往需要 root 权限的文件里写入内容
echo "192.168.1.100 my-server" | sudo tee -a /etc/hosts
tee -a 是追加模式。某些系统配置文件的修改,直接用 sudo echo xxx > file 会因为重定向是由 shell 执行的而没有 root 权限,换成 echo | sudo tee 就能绕过这个坑。
3.3 组合的威力:一个真实场景串起来
光介绍单个工具没意思,我给你来一个真实的组合场景。假设你要清理系统上历史遗留下来的临时文件,需求是:
- 找出
/var/log下所有超过 1GB 的.log文件 - 把清单打印出来,同时存一份到
big_logs.txt - 问你一句:这些加起来一共占了多少空间
命令行版本可以这么写:
bash复制find /var/log -name "*.log" -size +1G -exec ls -lh {} \; | tee big_logs.txt | awk '{sum += $5} END {print "总大小: " sum}'
这里 find -exec ls 输出的每一行里,第 5 列是文件大小(人类可读格式,比如 2.3G),awk 累加求和。有瑕疵,但思路是对的:每个工具贡献一点点,管道把它们的贡献串成一个整体。
这就是我理解的管道魔法——单个命令是音符,管道是乐谱,最终演奏的是整支曲子。
4. 第三层魔法:创意组合案例拆解
到了这一节,我要分享几个我在实际工作中用过、也在比赛里见过别人用得漂亮的管道组合。每一个我都会尽量讲清楚“为什么要这么组合”,而不是只贴命令。
4.1 案例一:一行命令找出攻击者 IP
有一次线上 Nginx 服务响应变慢,从几百毫秒飙到几秒。我第一时间怀疑是不是有恶意请求打进来。常规思路是拉访问日志,人工筛选可疑 IP。
我用一条管道组合快速定位:
bash复制# 找出访问量最高的前 20 个 IP,并统计各自产生的 4xx/5xx 状态码数量
awk '{print $1, $9}' access.log | awk '$2 >= 400 {print $1}' | sort | uniq -c | sort -rn | head -n 20
第一段 awk 把 IP 和状态码两列提取出来;第二段 awk 过滤出状态码是 4xx/5xx 的请求;剩下就是老朋友 sort | uniq -c | sort -rn | head 组合,输出攻击嫌疑最大的 IP 名单。
这条命令的亮点在于:我不用把几万行日志拖进 Excel,也不用写 Python 脚本,一条命令直接给出结论。后续如果要封禁 IP,把输出重定向到一个文本文件,再用 while read 循环生成防火墙规则即可。
4.2 案例二:用管道拼出实时监控面板
你可能觉得 top、htop 已经是监控工具的天花板了。但如果你不想装任何额外软件,管道组合也能拼出“准实时”监控面板。
需求:每 2 秒刷新一次,显示当前 CPU 占用最高的 5 个进程、内存占用最高的 3 个进程,以及系统负载。
bash复制watch -n 2 'ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head -n 6 && echo "---LOAD---" && uptime && echo "---MEM---" && free -h'
watch 负责定时刷新,里面的命令用 && 连接,每个子命令之间互不干扰。虽然这个例子核心不是 |,但 ps -eo ... --sort | head 才是在实时监控中真正干活的部分。
更有意思的玩法是,把管道输出接到 column 或 paste 命令,做成格式化报表:
bash复制# 查看当前 TCP 连接状态分布,格式化输出
ss -ant | tail -n +2 | awk '{print $1}' | sort | uniq -c | sort -rn | column -t
column -t 能把多列文本对齐成整齐的表格,特别适合在管道尾部做“美化”。
4.3 案例三:文本数据的快速透视
曾经有个需求:产品经理给我发了个几万行的大文本文件,里面是用户行为日志,要我快速分析出“不同用户各自的最活跃时段”。我用管道组合一分钟出结果。
文件格式大概是:user_id,action_time,比如 1001,2024-06-01 14:23:45。
目标:统计每个用户最常操作的小时区间(0-23 点)。
bash复制awk -F',' '{split($2, arr, ":"); hour = substr(arr[1], 12, 2); print $1, hour}' user_actions.log | sort | uniq -c | sort -k2,2n -k1,1nr | awk '{print $2, $3, $1}' | head -n 30
稍微拆一下:
awk -F','按逗号分列split($2, arr, ":")把时间字段切成时分秒数组substr(arr[1], 12, 2)从日期时间字符串里抠出小时部分
后面的管道依然是排序、统计、再排序。最后 awk 调整列顺序,让输出更符合阅读习惯。
这种“带一点编程逻辑的 awk + 管道统计”的组合,在处理 CSV 类文本时极其高效。
4.4 案例四:递归清理,同时展示清理过程
清理磁盘垃圾时,我想知道每个大目录分别占了多大空间,并且只保留最大的几项。
bash复制du -ah /var 2>/dev/null | sort -rh | head -n 20
du -ah 递归列出所有文件和目录大小(人类可读格式),sort -rh 按数值倒序排序,head 取前 20。这条命令在判断“磁盘到底被谁吃掉了”时,能一秒钟给你答案。
但如果你想真正清理,还可以把待删除候选文件过一遍 grep -v,排除掉不想动的目录:
bash复制du -ah /var 2>/dev/null | sort -rh | head -n 50 | grep -v -E "(/proc|/sys|/run)"
这就是管道组合里的“个性化过滤”,灵活得不像话。
5. 第四层进阶:深入管道内功心法
如果你的管道之旅只停留在“键盘敲得快”,那就错过了一些真正有意思的原理和技巧。这一节讲几个藏在表面之下的知识点,属于“知道就比别人强一截”的内功。
5.1 命名管道(FIFO):让通信跨命令、跨终端
普通管道 | 是临时存在的,连接着两个同时运行的进程,命令结束管道就消失。但有一种管道是可以用 mkfifo 显式创建出来的,它会在文件系统里以一个文件的形式存在,叫命名管道(FIFO)。
简单理解:普通管道是一次性的,命名管道是你先修好一条“水管”,之后再让任意两个进程接上去通信。
我第一次接触 FIFO 时觉得非常惊艳,因为它的用法完全颠覆了我对管道只能用在命令行的认知。
场景举例:一个程序持续输出数据,另一个程序想分时消费。由于普通管道要求两端必须同时启动,无法跨窗口合作,这时候 FIFO 就派上用场了。
bash复制# 窗口1:创建 FIFO,并让程序持续写入
mkfifo /tmp/myfifo
tail -f /var/log/nginx/access.log > /tmp/myfifo
# 窗口2:读取 FIFO 里的数据流
grep " 500 " < /tmp/myfifo
这里 tail -f 和 grep 不是同时由同一条命令启动的,它们可以跨终端协作,一边实时写,一边实时读。FIFO 天然支持这种“生产-消费”解耦模式。
5.2 进程替换:把命令输出伪装成文件
如果说管道是“用 | 连接”,那进程替换就是“用 <(...) 把一段命令的输出当成一个临时文件来用”。它最适合的场景是:某些命令只能读文件参数,不肯读标准输入。
最经典的是 diff 对比两个命令输出:
bash复制diff <(sort file1.txt) <(sort file2.txt)
正常你要先 sort file1.txt > 1.txt,再 sort file2.txt > 2.txt,然后 diff 两个临时文件,完事还要清理。进程替换一行搞定,完全不需要临时文件。它本质上是 bash 帮你创建了一个 /dev/fd/xx 的临时文件描述符,把命令输出接到这个文件描述符上。
这个技巧在写脚本时尤其有用,比如你想对比两个不同条件下的命令结果,进程替换能减少大量中间变量。
5.3 重定向与管道的混搭:2>&1 的学问
管道只连接标准输出,不连接标准错误。换句话说,grep "xxx" | wc -l 时,如果左边命令把错误信息输出到了 stderr,那这些错误信息不会进入管道,而是直接打到终端上。
这样一来,你会看到统计结果出现在终端,错误信息也出现在终端,两拨输出混在一起,看起来就像出了问题。
解决方法是先做重定向合并,把 stderr 并进 stdout:
bash复制# 合并 stdout 和 stderr 一起传给管道
your_command 2>&1 | grep "error"
# 或者用更简短的新语法
your_command |& grep "error"
|& 是 bash 提供的简写,等价于 2>&1 |。在写管道组合逻辑时,如果你预期命令会产生一些无害的报错(比如 find 遇到无权限目录),经常用 2>/dev/null 丢弃掉:
bash复制find / -name "*.conf" 2>/dev/null | head -n 10
5.4 SIGPIPE 与管道断裂:为什么你的命令“半路死了”
这是一个所有用管道的人终会撞上的现象:明明数据量很大,但命令很快就退出了,而且没报错。比如:
bash复制cat huge_file.txt | head -n 5
按理说 cat 要把整个文件输出完,但 head -n 5 只要 5 行,看到前 5 行就开心地退出了。这时候管道右边的读取端关闭了,左边 cat 继续往后写,操作系统会向它发送一个 SIGPIPE 信号,默认行为是终止进程。于是 cat 被系统“掐死”,不再继续读文件。
很多人会纳闷为什么 cat 只输出五行就退出,其实是 head 的存在让它提前“退休”。命令退出得干静利落,这正是符合预期的行为。但如果你写脚本时依赖 cat 的退出状态码,就得注意这一现象:cat 可能不是正常退出,状态码不是 0。
再比如 set -o pipefail 这个 shell 设置:默认管道返回的是最后一条命令的退出码,但加了这个设置后,只要管道里任何一条命令失败,整条管道的退出码就是非 0。这能有效防止“最后一个命令成功,前面全错”的假象。
bash复制set -o pipefail
your_flaky_command_that_fails | grep "something" | wc -l
如果 your_flaky_command 失败了,管道整体返回非 0,脚本就能及时发现。
6. 常见坑与排查技巧实录
现场实战中,管道命令出错率最高的地方往往不在逻辑复杂度上,而在一些不起眼的细节里。我把这些年踩过的坑整理出来,做成一个速查表式的列表,方便你对症下药。
| 现象 | 原因 | 解决方案 |
|---|---|---|
uniq -c 的结果不对 |
数据没有先排序,相同行不相邻 | 在 uniq 前加上 sort |
| 管道命令中途退出,没有报错 | 右边的 head 提前关闭,左边收到 SIGPIPE |
属正常行为;脚本里用 set -o pipefail 控制状态码 |
| 文件名含空格,处理结果错乱 | xargs 默认按空格拆分参数 |
使用 find -print0 + xargs -0 |
| 实时日志看不到新日志 | 展开了缓冲,grep 没实时输出 | 给 grep 加 --line-buffered 参数 |
| stderr 错误不进管道 | stderr 没有并入 stdout | 使用 2>&1 或 ` |
| 命令输出不是纯文本(比如二进制) | 管道不能直接处理二进制 | 先转换成文本格式(如 strings、hexdump) |
| 从文件里读到了 Windows 换行符 | 数据源来自 Windows | 用 sed 's/\r$//' 清理 |
6.1 缓冲区问题:实时流里的“隐形延迟”
grep 默认会做缓冲,但它对 stdout 的缓冲策略是:如果不是终端,就使用块缓冲(块缓冲),攒够 4KB 或 8KB 才批量输出。 这就造成了一个很头痛的现象:你用 tail -f file | grep keyword 监控日志,但新日志出现后,终端上迟迟不显示匹配行,隔一会儿才突然蹦出一堆。
解决办法就是给 grep 加 --line-buffered,让它改成行缓冲,每遇到一个换行就立即输出:
bash复制tail -f /var/log/nginx/access.log | grep --line-buffered "error"
awk 也有类似问题,它的默认 flush 策略同样可能导致延迟。遇到实时性要求高的场景,就用 fflush() 或者干脆选 grep --line-buffered 先过渡一层。
6.2 管道里的循环与死锁
新手写管道组合时最喜欢干的一件事,是在管道里加 for 循环:
bash复制# 危险示范
cat file.txt | while read line; do echo "$line" | tr 'a-z' 'A-Z'; done
问题在于,while 循环是在一个子 shell 里执行的,循环内对变量做的修改,循环结束后不会保留到当前 shell。最常见的翻车现场:
bash复制count=0
cat file.txt | while read line; do count=$((count+1)); done
echo $count # 输出仍旧是 0
因为 while 在管道后的子 shell 里执行,它修改的 count 影响不到父 shell。
要解决这个坑,两个思路:
- 别用管道,改用进程替换:
bash复制count=0
while read line; do count=$((count+1)); done < <(cat file.txt)
echo $count # 输出正确
- 如果坚持用管道,就要把后续逻辑放在同一条管道里:
bash复制cat file.txt | while read line; do count=$((count+1)); echo $count; done | tail -n 1
6.3 管道里藏了“看不见”的字符
Windows 和 Unix 的文本文件换行符不一样,Windows 用 \r\n,Unix 用 \n。如果你把一个在 Windows 上生成的配置文件或日志文件直接在 Linux 里管道处理,每行末尾都会多一个 \r。
排查技巧是:当你发现 wc -l 统计的行数异常、awk '{print $NF}' 取最后一列失败,或者 grep 匹配总是差一点时,大概率是换行符作怪。
用 cat -A 可以检查文件里藏了哪些特殊字符,\r 会显示成 ^M$。
bash复制cat -A suspicious_file.txt | head -n 5
# 输出可能长这样: hello^M$
清理方法很简单:
bash复制sed -i 's/\r$//' suspicious_file.txt
这个细节在一些命令行比赛里经常是“隐藏关卡”。你以为自己逻辑写对了,结果提交上去出了问题,就是个小到不能再小的字符在背后捣乱。
7. 一些走出比赛之外的个人体会
玩转了这些命令后,我对管道这件事有了点自己的理解,想分享给你。
最佳的管道组合不是“最短”,而是“最容易看懂”。有时候你为了省几个字符把命令压缩到极致,结果过了一个月回头自己都看不懂在干嘛。我在比赛里见过很多炫技之作,但真正让我觉得厉害的人,往往能用简单的命令拼接讲清楚复杂的逻辑,而不是硬塞一堆花哨参数。
管道命令的设计哲学,其实和写代码很像:每个模块只干一件事,模块之间的接口要干净简单。 Linux 命令们恰好都符合这个约定——它们默认从标准输入读、往标准输出写、报错走标准错误。这种“统一接口协议”,让任何两个程序都能无缝协作,这才是管道魔法真正来源。
根据我自己的经验,最快的提升方式不是背命令手册,而是给自己出题。比如“今天我想不开,能不能不用 Python,纯用 shell 把 /etc 目录下所有配置文件里 # 开头的注释行统计成一个列表,并按单词频率排序”。这种真实的小任务会让你被迫去寻找合适的命令、理解它们的行为、把它们正确串起来,比看十篇教程都管用。
最后再分享一个小技巧:alias 配合管道的组合。我给自己配了几个常用管道别名,比如:
bash复制alias topip='awk '\''{print $1}'\'' | sort | uniq -c | sort -rn | head'
alias hsize='du -sh * | sort -rh'
配置到 ~/.bashrc 里之后,日常工作几乎离不开它们。命令行有意思的地方就在于,你花的每一分钟去打磨它,都会在未来无数个重复操作里加倍还给你。希望这篇内容能给你一些启发,让你在命令行里找到属于自己的那种“管道里变魔法”的乐趣。
