我使用command | awk '{ print $1; }' | while read val ; do
循环执行命令输出。最近我想计算总和,我在bash
中发现了一些奇怪的行为:
test.txt的内容
100
200
300
test.sh的内容
sum='0'
cat test.txt | awk '{ print $1; }' | while read val ; do
sum=`expr $sum + $val`
echo "sum is now: $sum"
done
echo "FINAL SUM: $sum"
执行test.sh输出
sum is now: 100
sum is now: 300
sum is now: 600
FINAL SUM: 0
最终金额应该是600.我该怎么做才能解决这个问题?
答案 0 :(得分:2)
原因是使用了cat
,它产生了另一个子shell。这意味着sum
变量在第二个子shell中递增,然后在循环结束时超出范围(并返回其先前的0
值)。
尝试将循环更新为而不是使用cat
:
sum='0'
while read val ; do
sum=`expr $sum + $val`
echo "sum is now: $sum"
done < test.txt
echo "FINAL SUM: $sum"
如果你实际上不需要循环(即 - 如果你没有处理任何其他列/内容处理),你可以直接使用awk
并存储它的值进入sum
变量:
sum=`awk '{ sum += $1; } END { print sum }' test.txt`;
答案 1 :(得分:2)
不需要bash管。您可以使用awk
:
awk '{sum+= $1; printf "The sum is now: %s\n", sum } END { print "FINAL SUM:", sum }' file.txt
结果:
The sum is now: 100
The sum is now: 300
The sum is now: 600
FINAL SUM: 600
答案 2 :(得分:2)
要扩展新家具的状态,但是在某种程度上你可以使用arbritary输入命令,而不仅仅是cat
:
sum='0'
while read val ; do
sum=`expr $sum + $val`
echo "sum is now: $sum"
done < <(cat test.txt | awk '{ print $1 }')
echo "FINAL SUM: $sum"
将cat test.txt
替换为输出所需输入的任何命令。
答案 3 :(得分:0)
这种奇怪的行为实际上是由bash管道引起的
管道中的每个命令都在其自己的子shell中执行
将sum
视为while循环中的局部变量,这就是当你离开while循环时,sum
似乎没有设置的原因。
其他人提出的解决方案可以正常使用。