为什么不`seq 100 | (head -n1; tail -n1)`在Mac OSX上工作?

问题描述 投票:1回答:1

以下命令应该打印seq 100中的第一行和最后一行,但它只打印第一行:

seq 100 | (head -n1 ; tail -n1)
1

它适用于较大的序列,例如10,000:

seq 10000 | (head -n1 ; tail -n1)
1
10000

UPDATE

我选择了@ John1024的答案,因为我的问题是为什么这不起作用,他提供了一个可接受的答案。

此外,应该显然只是我的意见..现实是head不会这样工作...它可能会消耗更多的stdin而不是我想要的,并且没有为tail留下任何东西。

当然,首先提出这个问题的问题是尝试读取文件的第一行和最后一行。这是我基于GNU qazxsw poi提出的解决方案:

sed

或者更紧凑

sed -ne'1,9{p;b}' -e'10{x;s/$/--/;x;G;p;b}' -e':a;$p;N;21,$D;ba'

Example output:

*注意在我的Mac上,使用MacPorts,GNU sed -ne'1,9{p;b};10{x;s/$/--/;x;G;p;b};:a;$p;N;21,$D;ba' 被调用为sed。 Apple的内置gsed对于分号分隔表达式很挑剔,需要多个sed参数。这应该适用于Apple的-esed *

sed -ne'1,9{' -e'p;b' -e'}' -e'10{' -e'x;s/$/--/;x;G;p;b' -e'}' -e':a' -e'$p;N;21,$D;ba'

Explanation

seq 100 | gsed -ne'1,9{p;b}' -e'10{x;s/$/--/;x;G;p;b}' -e':a;$p;N;21,$D;ba' 1 2 3 4 5 6 7 8 9 10 -- 91 92 93 94 95 96 97 98 99 100 调用gsed -ne'没有自动打印模式空间

sed打印前9行

-e'1,9{p;b}'打印第10行,附加' - '分隔符

-e'10{x;s/$/--/;x;G;p;b}'打印最后10行

bash pipe seq
1个回答
6
投票

我在Linux上看到与GNU -e':a;$p;N;21,$D;ba'head相同的行为。

这取决于tail在退出之前消耗了多少输入。如果head -n1在退出之前读取所有stdin,那么head没有任何东西可以读取而且tail没有产生输出。

注意:

tail

在这里,我们可以看到$ seq 10000 | (head -n1 ; cat ) | head 1 1861 1862 1863 1864 1865 1866 1867 1868 消耗了前1860行。 head -n1命令查看所有剩余输入。

这是为什么?观察前1860行中有多少字节:

cat

可以合理地猜测,$ seq 1860 | wc 1860 1860 8193 首先从stdin读取8kB数据,然后打印第一行,并且看到它不需要更多数据,它就会退出。 stdin的其余部分可用于任何后续过程。

因此,使用head -n1产生的总输出小于8kB,seq 100读取所有stdin并且没有为head留下任何内容。 tail的产量超过8kB,seq 10000将无法读取管道中的所有数据。它留下的数据将可用于head

正如tail所指出的,这种行为的细节完全取决于实现,并且在任何软件升级时,它可能会改变。

© www.soinside.com 2019 - 2024. All rights reserved.