Bash
將標準輸出發送到鏈中的多個下游程序
我有一系列這樣執行的命令:
cmd1 < input > foo cmd2 < foo > bar cmd3 foo bar > output
有沒有辦法在沒有中間文件的情況下做到這
foo
一點bar
?我也想避免跑
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 ------------>|
這樣的事情,可能嗎?
rm -f fifo mkfifo fifo cmd1 <input | tee fifo | cmd2 | cmd3 fifo /dev/stdin >output
這將創建一個名為
fifo
. 第一個命令使用 . 寫入命名管道和第二個命令的標準輸入tee
。第三個命令從命名管道和標準輸入中讀取。
cmd3
沒有任何中間數據儲存在磁碟上,但是如果在管道緩衝區已滿之前沒有從命名管道中消耗,或者如果cmd2
與消耗的數據量相比產生的數據非常少,則管道可能會死鎖(而且,至關重要的是,在該管道的緩衝區已滿之前沒有產生足夠的cmd3
消耗)。fifo
您可以通過pv
使用諸如緩衝來自命名管道的數據之類的東西來解決這個問題,例如 withcmd3 <( pv --quiet <fifo ) /dev/stdin
,或在 writer 站點 withtee >( pv --quiet >fifo )
(或其某些變體)。