|
)功能,我可以将标准输入转发到一个或几个输出流。 我可以使用
tee
将输出拆分为单独的子进程。是否有一个命令可以将两个输入流连接在一起?
我该如何处理?去这个? diff如何工作?
#1 楼
就我个人而言,我最喜欢的(需要bash和其他大多数Linux发行版中标准的东西)细节可能在很大程度上取决于这两件事的输出以及您希望如何将它们合并...
命令1和命令2的内容在输出中依次排列:
cat <(command1) <(command2) > outputfile
或者两个命令都输出相同数据的替代版本并排查看(我将它与snmpwalk一起使用;一侧使用数字,另一侧使用MIB名称):
paste <(command1) <(command2) > outputfile
或者如果要比较两个相似命令的输出(例如在两个不同目录中的查找)
diff <(command1) <(command2) > outputfile
或者如果它们是某种排序的输出,则将它们合并:
sort -m <(command1) <(command2) > outputfile
或一次运行两个命令(虽然可能会有点混乱):
cat <(command1 & command2) > outputfile
<()运算符为每个命令设置一个命名管道(或/ dev / fd),将该命令的输出传递到命名管道(或/ dev / fd文件)中ndle参考),并在命令行上传递名称。 >()等效。您可以执行以下操作:
command0 | tee >(command1) >(command2) >(command3) | command4
例如将一个命令的输出同时发送到其他4个命令。#2 楼
您可以使用cat
将两个流附加到另一个,如大猩猩所示。还可以创建一个FIFO,将命令的输出定向到该FIFO,然后使用任何其他程序从FIFO中读取:
mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo
特别适用于仅写入或读取文件的程序,或仅将输出stdout / file的程序与仅支持另一个文件的程序混合使用的软件。
评论
这适用于pfSense(FreeBSD),而接受的答案则无效。谢谢!
–内森·斯托克斯(Nathan Stocks)
16年7月7日在15:05
#3 楼
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output
/tmp/p1
和/tmp/p2
是您的输入管道,而/tmp/output
是输出管道。评论
注意:除非()中的两个命令都在每一行上都刷新了它们的输出(以及其他一些原子性晦涩的POSIX规则),否则您最终可能会对cat的输入进行一些奇怪的加扰...
–freiheit
10年8月16日在18:41
您不应该使用分号代替&字符吗?
–萨米尔
15年7月4日在23:38
这是史诗般的东西
– Mobigital
19年5月22日在0:52
#4 楼
我为此创建了一个特殊的程序:fdlinecombine它读取多个管道(通常是程序输出)并将它们按行写入stdout(也可以覆盖分隔符)
评论
如广告般运作。感谢您将其公开。
– alexei
15年3月13日在22:49
#5 楼
我使用的一个非常酷的命令是tpipe
,您可能需要编译,因为它并不常见。它非常适合执行您所谈论的内容,而且非常干净,我通常会安装它。手册页位于http://linux.die.net/man/1/tpipe。当前列出的下载文件位于此归档文件http://www.eurogaran.com/downloads/tpipe/中。 这样使用,
## Reinject sub-pipeline stdout into standard output:
$ pipeline1 | tpipe "pipeline2" | pipeline3
#6 楼
这里要小心;仅仅抓住它们,最终可能会以您不想要的方式混合结果:例如,如果它们是日志文件,则您可能实际上并不希望从一个插入的行到另一个插入的行中间插入一行。如果可以的话,tail -f / tmp / p1 / tmp / p2>
/ tmp / output
工作。如果那还不行,那么您将不得不寻找可以进行行缓冲并且仅输出完整行的内容。 Syslog可以做到这一点,但是我不确定还有什么可能。
编辑:针对无缓冲读取和命名管道的优化:
考虑/ tmp / p1,/ tmp / p2 ,/ tmp / p3作为命名管道,由“ mkfifo / tmp / pN”创建。
tail -q -f / tmp / p1 / tmp / p2 | awk'{print $ 0>“ / tmp / p3”; close(“ / tmp / p3”); fflush();}'&
现在,通过这种方式,我们可以读取输出管道“ / tmp / p3”,该管道不受以下缓冲: /> tail -f / tmp / p3
存在一些小错误,您需要通过以下方式“初始化”第一个输入管道/ tmp / p1:
echo -n> / tmp / p1
为了拖尾,将首先接受来自第二个管道/ tmp / p2的输入,而不必等到/ tmp / p1。可能不是这样,如果您确定/ tmp / p1将首先接收输入。
还需要-q选项,以便尾部不打印有关文件名的垃圾。
评论
更为有用的是:“ tail -q -f / tmp / p1 / tmp / p2 | another_command”,因为它将逐行完成,并且使用-q选项将不会打印任何其他垃圾
– readyblue
2014-10-22 19:27
对于未缓冲的文件/命名管道,请使用:tail -q -f / tmp / p1 / tmp / p2 | awk'{print $ 0>“ / tmp / p3”; close(“ / tmp / p3”); fflush();}',现在/ tmp / p3甚至可以命名为pipe,您可以通过简单的tail -f / tmp / p3来读取它,所有这些都是UNBUFFERED =逐行=但是存在一些小错误。第一个文件/命名管道需要首先进行初始化,以便tail接受第二个文件的输出。因此,您需要回显-n> / tmp / p1,然后一切都会顺利进行。
– readyblue
14-10-22在20:47
#7 楼
最好的程序是lmerge
。与freihart的答案不同,它是面向行的,因此两个命令的输出不会互相干扰。与其他解决方案不同,它公平地合并了输入,因此没有命令可以控制输出。例如:$ lmerge <(yes foo) <(yes bar) | head -n 4
给出以下内容的输出:
foo
bar
foo
bar
评论
太棒了!我已经读了很多bash的联机帮助页,但是还没有选择
–哈维尔
10年8月16日在21:12
您可以在Linux文档项目的[高级bash脚本指南](tldp.org/LDP/abs/html/process-sub.html)中找到参考。
–brice
2011年7月8日15:50
我能够通过grep --line-buffered-方便地同时插入多个日志文件的尾部来防止交错行。参见stackoverflow.com/questions/10443704/line-buffered-cat
– RubyTuesdayDONO
13年4月8日在20:47