我有一个 bash 脚本,对于一组中的每个文件,greps 文件中的每一行以查找字符串。然后,它用逗号分割该行,将第 7 个元素转换为浮点数,并按该值递增运行总计。
它看起来像这样:
for filename in data*.CSV; do
echo $filename
ACTUAL_COST=0
grep '040302010' $filename | while read -r line ; do
IFS=',' read -a array <<< "$line"
ACTUAL_COST=$(echo "$ACTUAL_COST + ${array[7]}" | bc)
echo $ACTUAL_COST
done
echo $ACTUAL_COST
done
但我遇到的问题是这会产生如下输出:
53.4
72.2
109.1
0
最后一个值始终为 0。谷歌搜索了一下后,我认为这是因为循环while
在子 shell 中执行,因此外部变量没有更改。
我知道我可能需要执行函数中的内部循环。
答案1
这不是你编写 shell 脚本的方式。您正在为文件的每一行按顺序运行多个命令!
在这里你想要类似的东西:
awk -F, '/040302010/ {actual_cost += $7}
ENDFILE {print FILENAME ":", +actual_cost; actual_cost=0}
' data*.CSV
(假设 GNU awk)。
那是一所有文件的命令总数。
答案2
为了避免使用子 shell,您可以使用以下命令:
while read -r line
do
your_stuff
done < <(grep '040302010' $filename')
这样您就可以将结果填充到变量中。
答案3
引入另一个命令替换可能会很方便,其中核心循环逻辑在函数中定义:
sum_cost() {
sum=0
while read -r line ; do
IFS=',' read -a array <<< "$line"
sum=$(echo "$sum + ${array[7]}" | bc)
done
echo $sum
}
for filename in data*.CSV; do
echo $filename
ACTUAL_COST=$(grep '040302010' $filename | sum_cost)
echo $ACTUAL_COST
done