
セット内の各ファイルについて、ファイルの各行を把握して文字列を検索するbashスクリプトがあります。次に、行をコンマに分割し、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
サブシェルで実行されるため、外部変数は変更されないようです。
関数内で内部ループを実行する必要があるかもしれません。
答え1
これはシェルスクリプトを書く方法ではありません。ファイルの各行に対して複数のコマンドを順番に実行しています!
ここでは、次のようなものが欲しい:
awk -F, '/040302010/ {actual_cost += $7}
ENDFILE {print FILENAME ":", +actual_cost; actual_cost=0}
' data*.CSV
(GNU awkを仮定)。
それは一つすべてのファイルのコマンドの総数。
答え2
サブシェルの使用を防ぐには、次のコマンドを使用できます。
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