输出到文件,然后使用文件作为输入

输出到文件,然后使用文件作为输入

有没有更短的写法?基本上将命令输出到文件,然后使用该文件作为下一个命令的输入。我还想保留该文件以供日后查看。

cmd1 > verylong.txt; cmd2 < verylong.txt

我知道我能做到

cmd1 | tee verylong.txt | cmd2

但由于我预计“verylong.txt”是一个巨大的文件,我认为使用管道效率会较低,因为它将整个文件保存在内存中。而如果我使用文件输入,那么它会一次处理一行。 (或者我的假设是错误的?)

如果我能做一些像这样优雅的事情那就太好了

cmd1 > verylong.txt > cmd2

答案1

据我所知,cmd1 | tee verylong.txt | cmd2不会将整个文件保存在内存中。事实上,如果cmd2在消耗其输入之前等待太长时间,cmd1则可能会阻塞调用write并仅在cmd2再次开始读取时解锁。

原因是管道有一个缓冲区,默认情况下该缓冲区被限制在一定的合理尺寸内

当然,如果(或类似的情况)在命令能够写入其输出之前必须读取整个输入,情况可能会有所cmd2不同sort。在这种情况下,整个文件内容可能保存在cmd2内存中,但这与管道或中间文件是否用于该命令的输入无关。

答案2

已经给出的答案是正确的。但如果您的目标是有选择地阅读您的verylongfile.txtw/ cmd2sed可能是另一种选择。

cmd1 | sed -e 'w verylongfile.txt' -e '/notinteresting/d' | cmd2

sed会将其所有输入写入输出文件,但仅写入与管道地址w不匹配的位。/notinteresting/或者您可能会否定该操作,该操作将仅将与管道地址/interesting/!d匹配的行写入。interesting

如果这不是您的目标,tee请改为使用 - 它是一种更有效的工具,可以将其全部输入写入输出文件和管道。

答案3

对于 tee 和 subshel​​l 有一个巧妙的技巧:

cat source.lst | tee >(doSomething.sh) >(somethingElse.sh) | somethingFinal.sh

我以前做过这个

pv -perl source.list | tee >(doSomething.sh) >(somethingElse.sh) | md5sum

pv将为您提供进度条、预计到达时间和运行线路总数。然后,source.lst 将被提供给 doSomething.sh 和 someElse.sh(并且在不同的 CPU 上!)最后,我们将获得该大文件的 md5sum,仅用于学术目的。

答案4

简单的两行批处理文件有什么问题?喜欢:

Cmd1 >filespec
Cmd2 <filespec

或者

cmd1 >filespec
cmd2 filespec

无论哪种方式,文件都会保留在大容量存储中。

相关内容