awk 출력의 각 줄에 추가를 수행하는 방법은 무엇입니까?
예를 들어
cat foo | awk '{print $1}
42
42
42
42+42+42(126)에 대한 답을 구하고 있습니다.
이 작업을 수행하기 위해 for 루프를 작성하려고 하는데 더 쉬운 방법이 있을 것입니다.
#Not Working, and way too complex
cat foo |awk '{ print $1 }'|for i in $1 do; foo=$(( foo+$(i) )) done| echo $foo
파이프할 수는 있지만 wc -l
줄 수만 인쇄할 뿐 평가되지는 않습니다.
awk에서 각 줄을 평가하는 방법은 무엇입니까?
답변1
귀하의 예를 사용한 기본 접근 방식 :
awk '{sum+=$1} END {print sum}' file
답변2
awk 프로그램을 제어할 수 있는 경우 @jasonwryan이 제안한 대로 awk에 추가하세요.
awk가 출력한 숫자를 실제로 합산하려면 출력을 다음 중 하나로 파이프하십시오.
| { tr '\n' '+' ; echo 0; } | bc
| { while read line; do ((sum+=line)); done; echo $sum; }
두 번째 예에서 echo 명령은 그룹화 중괄호 안에 있습니다. bash는 서브셸에서 파이프를 실행하므로 $sum 변수에 대한 변경 사항은 서브셸이 종료될 때 존재하지 않습니다.
답변3
Bash는 소수를 처리할 수 없지만 정수에 대한 간단한 연산은 처리할 수 있습니다. 다음과 같은 트릭을 사용하면 됩니다.프로세스 교체루프 외부에서 변수에 액세스할 수 있도록 설정합니다.
n=0;while read i; do let n+=$i; done < <(awk '{print $1}' foo); echo $n;
또는
n=0;while read i; do n=$((n+i)); done < <(awk '{print $1}' foo); echo $n;
이는 항상 0인지 n=0
확인하기 위한 것입니다 $n
. 그렇지 않으면 이 명령을 두 번째로 실행하면 126 대신 252가 반환됩니다.
가장 간단한 방법은 gawk
계산을 수행하는 것이지만 Perl 단일 라이너를 사용할 수도 있습니다.
awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'
이 -l
플래그는 개행 문자( chomp
)를 제거하고 인쇄된 각 문자열의 끝에 1을 추가합니다. 이는 -n
파일을 한 줄씩 읽고 각 줄을 로 저장하고 $_
제공된 스크립트를 실행하는 것을 의미합니다 -e
.
아니면 Perl에서 모든 작업을 수행합니다.
perl -alne '$k+=$F[0];END{print "$k"};' foo
-a
자동 줄 분할을 켜는 Perl 플래그 (예 gawk
: . 기본적으로 필드는 공백으로 구분되지만 를 사용하여 변경할 수 있습니다 -F
. 결과 필드는 @F
배열로 저장되므로 첫 번째 필드는 입니다 $F[0]
.
답변4
이와 같은 간단한 합계에 일반적으로 사용하는 한 줄 접근 방식은 xargs로 파이프하여 awk의 모든 출력을 한 줄로 가져온 다음 sed를 사용하여 공백을 더하기 기호로 변환하고 마지막으로 계산을 위해 bc로 변환하는 것입니다.
cat foo | awk '{print $1} | xargs | sed -e 's/ /+/g' | bc