bash script2023. 9. 15. 09:03

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/618377

텍스트 파일에 각 항목별로 값이 있을 때, 같은 항목끼리 모아서 그 합을 구하는 방법이다. 간단한 예시를 생각해 보면 쉽게 감이 잡힐 것이다.

텍스트 파일 my_data.txt의 내용이 아래와 같다고 가정하자. 각 항목의 구분자는 탭(tab)이다.

# my_data.txt 파일 내용 확인(구분자는 탭)
cat my_data.txt
2018.1.3 apple 10
2018.1.3 orange 3
2018.2.5 pineapple 7
2018.3.10 apple 2
2018.3.15 pineapple 10
2018.3.30 apple 9

위와 같이 날짜마다 어떤 과일을 몇개 팔았는지 기록했다고 생각해 보자. 이제 여기서 각 과일별로 총 몇개씩 판매했는지 알고 싶은 것이다. 첫번째 항목은 날짜이므로 무시하고, 두번째 항목을 기준으로 하여 세번째 항목을 합산하는 것이다. 아래와 같이 하면 되겠다.

awk -F '\t' '{ x[$2]+=$3 } END { for (i in x) print i "\t" x[i] }' my_data.txt
orange 3
apple  21
pineapple  17

항목 구분자가 탭이므로 -F 옵션으로 구분자를 탭(\t)으로 지정했다.

awk 스크립트의 내용을 보자면, 파일을 한줄씩 읽어서 작업하는데 배열 x의 인덱스를 두번째 항목($2)으로 정한 후에 값은 세번째 항목($3)을 합산하도록 했다(x[$2]+=$3). awk의 배열은 기본적으로 연관배열(associative array)이므로 인덱스가 문자열이 될 수도 있다(예: x[apple]=1).

END 이후 부분은 파일을 다 읽은 후에 마지막으로 실행된다. 여기서 for 반복문으로 배열 x의 인덱스와 값을 출력했다.

만약 위의 예시에서 2018년 3월 한달 동안 어떤 과일을 몇개 팔았는지 계산하고 싶다면 아래와 같이 하면 될 것이다.

cat my_data.txt | grep "^2018\.3\." | awk -F '\t' '{ x[$2]+=$3 } END { for (i in x) print i "\t" x[i] }'

파일에서 문자열 "2018.3."으로 시작되는 항목만 grep으로 선별한 후에 그 결과를 awk로 넘겨서 계산하면 된다.

위의 예시에서 만약 과일 종류나 날짜와 무관하게 과일이 총 몇개가 팔렸는지 계산하는 경우는 더 간단하다. 항목 구분이 필요 없으므로 연관 배열도 사용할 필요가 없이 아래와 같이 세번째 항목만 모두 더해서 출력하면 되겠다.

awk -F '\t' '{ x+=$3 } END { print x }' my_data.txt

728x90
Posted by 반달가면