我可以链接多个命令并使所有命令从stdin获取相同的输入吗?

2 unix bash shell awk

在bash中,有没有办法链接多个命令,所有命令都从stdin获取相同的输入?也就是说,一个命令读取stdin,进行一些处理,将输出写入文件.链中的下一个命令获得与第一个命令相同的输入.等等.

例如,考虑通过过滤内容将大文本文件拆分为多个文件.像这样的东西:

cat food_expenses.txt | grep "coffee" > coffee.txt | grep "tea" > tea.txt | grep "honey cake" > cake.txt
Run Code Online (Sandbox Code Playgroud)

这显然不起作用,因为第二个grep获取第一个grep的输出,而不是原始文本文件.我试过插入发球台,但这没有用.是否有一些bash魔法可以导致第一个grep将其输入发送到管道而不是输出?

顺便说一句,拆分文件就是一个简单的例子.考虑拆分(通过模式搜索进行文件传输)来自网络的连续实时文本流,并将输出写入不同的命名管道或套接字.我想知道是否有一种简单的方法可以使用shell脚本来完成它.

(这个问题是我之前的一个清理版本,基于指出不清楚的回复)

Mar*_*gar 10

对于这个例子,你应该使用awk作为半无用的建议.

但是通常要让N个任意程序读取单个输入流的副本,您可以使用tee和bash的进程输出替换运算符:

tee <food_expenses.txt \
  >(grep "coffee" >coffee.txt) \
  >(grep "tea" >tea.txt) \
  >(grep "honey cake" >cake.txt)
Run Code Online (Sandbox Code Playgroud)

请注意,这>(command)是一个bash扩展.


Bri*_*new 5

显而易见的问题是,为什么要在一个命令中执行此操作?

如果你不想编写脚本,并且想要并行运行东西,bash支持子shell的概念,并且它们可以并行运行.通过将命令放在括号中,您可以同时运行greps(或其他),例如

$ (grep coffee food_expenses.txt > coffee.txt) && (grep tea food_expenses.txt > tea.txt) 
Run Code Online (Sandbox Code Playgroud)

请注意,在上面您cat可能是多余的,因为grep采用输入文件参数.

您可以(改为)通过不同的流重定向输出.您不限于stdout/stderr,但可以根据需要分配新流.除了这里的例子之外,我不能就此提出更多建议