(head; tail) < file工作怎么样?请注意,cat file | (head;tail)没有.
此外,为什么(head; wc -l) < file给0了输出wc?
注意:我理解头尾的工作原理.只是不是这些特定调用涉及的微妙之处.
rob*_*off 19
对于OS X,您可以查看源代码head和源代码,tail以找出正在发生的一些事情.在这种情况下tail,你会想看看forward.c.
所以,事实证明这head并没有做任何特别的事情.它只是使用stdio库读取它的输入,因此它一次读取一个缓冲区并且可能读取太多.这意味着cat file | (head; tail)不适用于小文件,其中head缓冲使其读取最后10行中的一些(或全部).
另一方面,tail检查其输入文件的类型.如果它是一个常规文件,tail则搜索结束并向后读取,直到找到足够的行发出.这就是(head; tail) < file适用于任何常规文件的原因,无论大小如何.
你可以看看源head和tailLinux上也一样,但它更容易,只需使用strace,就像这样:
(strace -o /tmp/head.trace head; strace -o /tmp/tail.trace tail) < file
Run Code Online (Sandbox Code Playgroud)
看看/tmp/head.trace.您将看到该head命令尝试通过读取标准输入(文件描述符0)来填充缓冲区(在我的测试中为8192个字节).根据大小file,它可能会也可能不会填充缓冲区.无论如何,我们假设它在第一次读取时读取了10行.然后,它用于lseek将文件描述符备份到第10行的末尾,实质上是"读取"它读取的任何额外字节.这是有效的,因为文件描述符在普通的可搜索文件上打开.所以(head; tail) < file适用于任何可搜索的文件,但它不会cat file | (head; tail)起作用.
在另一方面,tail确实没有(在我的测试),寻求结束和倒读,像它在OS X上至少,它不读取所有的方式回到文件的开头.
这是我的考试.创建一个小的12行输入文件:
yes | head -12 | cat -n > /tmp/file
Run Code Online (Sandbox Code Playgroud)
然后,试试(head; tail) < /tmp/fileLinux.我用GNU coreutils 5.97得到这个:
1 y
2 y
3 y
4 y
5 y
6 y
7 y
8 y
9 y
10 y
11 y
12 y
Run Code Online (Sandbox Code Playgroud)
但是在OS X上,我得到了这个:
1 y
2 y
3 y
4 y
5 y
6 y
7 y
8 y
9 y
10 y
3 y
4 y
5 y
6 y
7 y
8 y
9 y
10 y
11 y
12 y
Run Code Online (Sandbox Code Playgroud)
这里的括号创建一个subshell解释器的另一个实例来运行里面的命令,有趣的是子shell充当单个stdin/stdout组合; 在这种情况下,它将首先连接stdin head,回显前10行并关闭管道,然后subshell连接其stdin tail消耗其余的stdin 并将最后10行写回到stdout,但子shell接受两个输出并写入它们作为自己的标准输出,这就是它出现组合的原因.
值得一提的是,同样的效果可以用实现命令分组一样{ head; tail; } < file是便宜,因为它不会产生庆典的另一个实例.
| 归档时间: |
|
| 查看次数: |
8112 次 |
| 最近记录: |