有没有更短的写法?基本上将命令输出到文件,然后使用该文件作为下一个命令的输入。我还想保留该文件以供日后查看。
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.txt
w/ cmd2
,sed
可能是另一种选择。
cmd1 | sed -e 'w verylongfile.txt' -e '/notinteresting/d' | cmd2
sed
会将其所有输入写入输出文件,但仅写入与管道地址w
不匹配的位。/notinteresting/
或者您可能会否定该操作,该操作将仅将与管道地址/interesting/!d
匹配的行写入。interesting
如果这不是您的目标,tee
请改为使用 - 它是一种更有效的工具,可以将其全部输入写入输出文件和管道。
答案3
对于 tee 和 subshell 有一个巧妙的技巧:
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
无论哪种方式,文件都会保留在大容量存储中。