Bash: while 루프에서 변수를 늘리나요?

Bash: while 루프에서 변수를 늘리나요?

세트의 각 파일에 대해 파일의 각 줄을 파악하여 문자열을 찾는 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

관련 정보