チェーン内の複数のダウンストリームプロセスに標準出力を送信する

チェーン内の複数のダウンストリームプロセスに標準出力を送信する

次のように実行される一連のコマンドがあります。

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番目のコマンドは、名前付きパイプと標準入力から読み取られます。

ディスcmd3cmd2​これは、パイプcmd3バッファがいっぱいになるまで十分な消費を生成しないことです。fifo可能作成者サイト(またはそのバリエーション)でpv使用される名前付きパイプのデータバッファリングなどの方法を使用して、この問題を解決してください。cmd3 <( pv --quiet <fifo ) /dev/stdintee >( pv --quiet >fifo )

関連情報