排序文本/CSV文件时,GNU手册保留表头命令的原理疑问
解析GNU手册中排除表头排序的命令原理
场景说明
现有文件file1内容如下:
Name Age Charlie 34 Alice 25
直接执行排序命令sort -k2b,2 file1时,表头会被纳入排序,输出结果不符合预期:
Alice 25 Charlie 34 Name Age
可以用以下命令实现表头保留+内容排序:
head -1 file1 ; (sed -n '2,$p' file1|sort -k2b,2)
但GNU核心工具手册给出了另一种写法:
( sed -u 1q ; sort -k2b,2 ) < file1
很多人会疑惑:这个命令为什么不会重复输出表头?sed读取首行后,sort还能读取剩余内容吗?
核心原理拆解
这个命令能正常工作,关键在于Shell命令组的输入共享和sed的参数特性:
- 命令组共享输入流:括号
(...)是Shell的命令组,整个组共享同一个标准输入(即< file1重定向的文件内容)。sed和sort不是各自读取完整文件,而是按顺序读取同一个输入流的不同部分。 sed -u 1q的行为:-u开启无缓冲模式,让sed读取一行就立刻输出,避免缓冲延迟。1q表示读取第1行后直接退出sed程序。所以sed只会读取输入流的第一行(表头)并输出,随后停止读取。
sort接续读取剩余内容:当sed退出后,命令组里的sort会从输入流的当前位置(第2行开始)读取剩下的所有内容,执行排序后输出。
整个流程中,输入流是被sed和sort依次读取的,没有重复读取,因此表头只会被输出一次,最终结果就是表头+排序后的内容,完全符合需求。
内容的提问来源于stack exchange,提问作者FondDuLac
相关产品推荐
相关产品推荐

