次のように実行される一連のコマンドがあります。
cmd1 < input > foo
cmd2 < foo > bar
cmd3 foo bar > output
中間ファイルなしでfoo
これを行う方法はありますかbar
?
また、このタスクを2回実行することを避けたいと思いますcmd1
。
cmd3 <(cmd1 < input) <(cmd1 < input | cmd2) > output
3つのコマンドをすべて実行するのに数時間かかることがあり、ファイルサイズは1GBから100GB(生物情報学)です。
以下は人為的ですが、実行可能な例です。
function cmd1 { sed -r 's/[246]/x/g'; }
function cmd2 { sed -r 's/[135]/-/g'; }
function cmd3 { paste $1 $2; }
seq 10 > input
cmd3 <(cmd1 < input) <(cmd1 < input | cmd2) # cmd1 runs twice
出力
1 -
x x
3 -
x x
5 -
x x
7 7
8 8
9 9
10 -0
これが役に立つかどうかはわかりませんが、データが次のように流れたいと思います。
input --> cmd1 ---> cmd2 -->|
| |--> cmd3 --> output
------------>|
https://unix.stackexchange.com/a/43536近いですが十分ではありません。
答え1
これは可能ですか?
rm -f fifo
mkfifo fifo
cmd1 <input | tee fifo | cmd2 | cmd3 fifo /dev/stdin >output
これにより、名前付きパイプが作成されますfifo
。最初のコマンドは名前付きパイプへの書き込みを使用し、2番目のコマンドは標準入力を使用しますtee
。 3番目のコマンドは、名前付きパイプと標準入力から読み取られます。
ディスcmd3
cmd2
これは、パイプcmd3
バッファがいっぱいになるまで十分な消費を生成しないことです。fifo
可能作成者サイト(またはそのバリエーション)でpv
使用される名前付きパイプのデータバッファリングなどの方法を使用して、この問題を解決してください。cmd3 <( pv --quiet <fifo ) /dev/stdin
tee >( pv --quiet >fifo )