Bash

流程替換的管道輸出到變數

  • May 13, 2021

我有一組非常複雜的命令:

command | ... | ... | tee >(grep -c '[^3]$') >(grep -c '[^35]$') 1>/dev/null

我不想有一個臨時文件來保存輸出,因為它非常大。我試過做>(grep -c '[^3]$' | read variable)>(grep -c '[^3]$' | read variable2)但我猜有點不起作用,因為程序替換的子 shell 呼叫。

我該怎麼做才能將輸出直接傳遞給多個變數?甚至可能嗎?

現在我有這個解決方法:

var=$(command ... | ... | ... | tee >(grep -c '[^3]$') >(grep -c '[^35]$') 1>/dev/null)
var1=$(tail -1 <<< $var)
var2=$(head -1 <<< $var)

但我認為它很笨拙,看起來不太好。我知道我可以 grep 進入另一個文件,但我也不喜歡它。

提前致謝。

使用awk, 而不是tee-ing 到兩個 grep 程序替換。例如:

command | ... | ... | awk '
    /[^3]$/  { c1++; next };
    /[^35]$/ { c2++; next };
    END { print c1, c2 > counts.txt }'

read var1 var2 < counts.txt
rm counts.txt

如果您不想使用臨時文件,可以這樣做:

read var1 var2 < <(command | ... | ... | awk '
        /[^3]$/  { c1++; next };
        /[^35]$/ { c2++; next };
        END { print c1, c2 }')

首先,您將命令鏈中的標準輸出發送到/dev/null,因此您的分配可能會分配一個空值。刪除它。看起來您正在嘗試僅擷取輸出的第一行和最後一行;這在單行中可能很棘手,但awk應該能夠處理它:

var="$(command ... | [...] | tee [...] | awk 'NR==1{print $0} END { print $0}')"

然而,管道是簡單的生物。它們有一個輸入和一個輸出。您不能(輕鬆)使用管道將數據發送到多個地方。你能得到的最接近的是使用命名管道,它本質上是你試圖避免的臨時文件(技術上不正確;FIFO隊列與文件不同,但我正在簡化)。

引用自:https://unix.stackexchange.com/questions/649553