ファイルとして出力し、ファイルを入力として使用する

ファイルとして出力し、ファイルを入力として使用する

短く書く方法はありますか?デフォルトでは、コマンドをファイルに出力し、そのファイルを次のコマンドの入力として使用します。後で見るためにファイルをアーカイブしたいと思います。

cmd1 > verylong.txt; cmd2 < verylong.txt

私もできることを知っています

cmd1 | tee verylong.txt | cmd2

しかし、「verylong.txt」は巨大なファイルになると予想しているので、パイプを使用するとファイル全体がメモリに保存されるため、効率が悪くなると思います。一方、ファイル入力を使用すると、一度に1行ずつ処理されます。 (それとも私の推測は間違っていますか?)

こんなエレガントなことができればとても良いと思います。

cmd1 > verylong.txt > cmd2

答え1

私が知っている限り、cmd1 | tee verylong.txt | cmd2ファイル全体はメモリに保存されません。実際にcmd2入力を消費する前に待機しすぎると、cmd1呼び出しをブロックしwritecmd2再読み込みを開始したときにのみロックを解除できます。

その理由は、パイプに基本的にバッファがあるからです。特定の合理的なサイズに制限

もちろん、コマンドが出力を書き込む前に入力全体を読み取る必要がある場合(または同様の場合)、状況はcmd2異なる場合がありますsort。この場合、ファイル全体の内容はcmd2メモリに保持されますが、これはコマンドへの入力としてパイプまたは中間ファイルが使用されているかどうかには関係ありません。

答え2

すでに与えられた答えは正しいです。ただし、目標がverylongfile.txtw /を選択的に読むcmd2ことであればsed、他のオプションがあるかもしれません。

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

sedすべての入力を出力ファイルに書き込みますが、wパイプアドレスと一致しないビットのみを書き込みます。あるいは、パイプアドレスに一致する行のみを作成する/notinteresting/操作を無効にすることもできます。/interesting/!dinteresting

これが目標でない場合は、tee代わりに使用してください。すべての入力を出力ファイルとパイプに書き込むためのより効率的なツールです。

答え3

ティーとサブシェルのためのきちんとしたトリックがあります。

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

単純な2行バッチファイルにはどのような問題がありますか?良い:

Cmd1 >filespec
Cmd2 <filespec

または

cmd1 >filespec
cmd2 filespec

いずれにしても、ファイルは大容量ストレージに残ります。

関連情報