Linux
向前輸出每一行然後向後輸出的命令
我正在尋找一個“元命令”xyz,這樣:
(echo "foo"; echo "bar") | xyz rev
將返回:
foo oof bar rab
我想避免使用臨時文件,即我正在尋找比以下更簡潔的解決方案:
tempfile=$(mktemp) cat > $tempfile cat $tempfile | rev | paste $tempfile -
(當然,我想要一個通用的解決方案,對於任何命令,而不僅僅是
rev
,您可以假設該命令為每個輸入行準確輸出一行。)Zsh 解決方案也是可以接受的。
由於 stdio 緩衝的工作方式,在大多數情況下會出現很多問題。linux 的一種解決方法可能是使用該
stdbuf
程序並使用 coproc 執行命令,因此您可以顯式控制輸出的交錯。以下假設該命令將在每行輸入之後輸出一行。
#!/bin/bash coproc stdbuf -i0 -o0 "$@" IFS= while read -r in ; do printf "%s " "$in" printf "%s\n" "$in" >&${COPROC[1]} read -r out <&${COPROC[0]} printf "%s\n" "$out" done
如果需要更通用的解決方案,因為 OP 只要求程序的每一行輸入最終輸出一行而不是立即輸出,那麼需要更複雜的方法。創建一個事件循環,
read -t 0
用於嘗試從標準輸入和協同程序中讀取,如果兩者的“行號”相同,則輸出,否則儲存該行。如果在任何一輪事件循環中都沒有準備好,為了避免使用 100% 的 cpu,然後在再次執行事件循環之前引入一個小的延遲。如果該過程輸出部分行,則會出現額外的複雜情況,這些需要被緩衝。如果需要這個更通用的解決方案,我會使用expect來編寫它,因為它已經很好地支持處理多個輸入流上的模式匹配。但是,這不是 bash/zsh 解決方案。