将过程替换的输出通过管道传递给变量

将过程替换的输出通过管道传递给变量

我有一组非常复杂的命令:

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 到另一个文件中,但我也不喜欢它。

提前致谢。

答案1

使用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 }')

答案2

首先,您将命令链中的标准输出发送到/dev/null,因此您的分配可能会分配一个空值。删除它。看起来您正试图仅捕获输出的第一行和最后一行;这在一行中可能很棘手,但awk应该能够处理它:

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

然而,管道是简单的生物。它们有一个输入和一个输出。您不能(轻松)使用管道将数据发送到多个位置。你能得到的最接近的是使用命名的管道,本质上是您试图避免的临时文件(技术上不正确;先进先出队列与文件不同,但我正在简化)。

相关内容