如何在管道中的同一位置有多个命令(收集在一起)?即,管道之前的内容被分别和顺序地送入这些命令中的每一个,并且它们的组合输出被馈送到管道的下一步骤。例如,我怎么能对这个管道进行一些变化
echo -e "1\n2\n3" | { head -1; tail -1; } | xargs echo
打印1 3
,而不只是1
?
由于
答案 0 :(得分:3)
管道之前的内容分别按顺序送入每个命令,并将它们的组合输出送入管道的下一步
由于管道的性质,这是不可能的。从管道读取数据后,它将从管道中删除。这就是为什么只有一个读者。
我会将第一个命令的输出复制到一个临时文件中,然后将其提供给命令head
和tail
。如果您在子shell中启动head
和tail
,则可以将其合并输出提供给另一个命令:
顺便说一句,大括号之间的代码块不会启动子shell。你需要使用括号。以下命令似乎最接近您的要求:
echo -e "1\n2\n3" > file.tmp ; ( head -1 file.tmp ; tail -qn1 file.tmp; rm file.tmp ) | next_command
关于特殊用例:打印文件中的第一行和最后一行
我会将sed
用于此目的:
sed -n '1p;$p'
这将打印文件的第一行和最后一行。但是它仅适用于包含至少两行的文件。如果文件包含一行,则会打印两次。您可以使用以下命令绕过此限制:
sed -n 'x;s/^/1/;x;1p;${x;/11/{x;p}}'
上面的命令在每一行的保持缓冲区中添加1
。在脚本结束时(可能在第一行之后),它会检查保持缓冲区中是否至少有两个1
,如果这是真的,则打印最后一行。