1. 사용 명령어 |
(1) awk
2. 키워드 & 사용처 |
(1) 키워드
평균값, CSV 파일
(2) 사용처
CSV 파일에서 특정 컬럼값의 평균값을 계산해서 파일로 출력하고 싶을 때 사용합니다.
3. 실행 예제 |
$ cat data.csv <- 자료 파일 확인
0001,Kim,45
0002,Lee,312
0003,Park,102
0004,Kang,3
$ ./csv-avg.sh data.csv
$ cat data.avg <- 평균값이 기록된 [파일명.avg]이 생성됨
115.5
4. 스크립트 |
#!/bin/sh
# CSV 파일이 존재하지 않으면 종료
if [ ! -f "$1" ]; then ①
echo "대상 CSV 파일이 존재하지 않습니다 : $1" >&2 ①
exit 1 ①
fi
# 확장자를 제외한 파일명 취득
filename=${1%.*} ②
awk -F, '{sum += $3} END{print sum / NR}' "$1" > ${filename}.avg ③
5. 해설 |
이 스크립트는 명령행 인수를 지정한 CSV 파일의 세 번째 컬럼에서 값의 평균값을 계산해서 출력합니다. 평균값은 우너본 파일명에 확장자 .avg를 붙인 파일에 출력합니다. 여러 CSV 파일마다 평균값을 출력하고 싶을 때 사용하면 됩니다.
여기에서 사용하는 CSV 파일은 "ID번호, 이름, 점수" 형식이라고 가정합니다.
셸 스크립트에서 수치 계산은 expr 명령어를 자주 사용합니다. 하지만 expr은 정수 계산만 가능하므로 소수가 포함된 계산에서는 사용할 수 없습니다. 셸 스크립트에서 소수를 포함한 계산을 할 때는 bc 명령어를 사용하기도 하는데 여기에서는 간단히 awk 명령어르르 사용해봅니다.
①에서 대상 CSV 파일 존재를 확인합니다. -f 옵션은 대상이 일반 파일인지 확인하는데 부정 연산자 !를 함께 서서 대상이 일반 파일이 아니면 에러를 표시하고 종료합니다.
②에서 파일 확장자를 제외한 파일명을 취득합니다. 여기서 셸 파라미터 확장을 사용한 문장열 치환으로 셸 변수 $1에서 '.(점)과 그 이후에 이어진 임의 문자열'을 제거합니다. $1에는 명령행 인수로 CSV 파일이 넘어오므로 확장자 .csv를 제거할 수 있게 됩니다.
③은 평균값을 계산하는 awk 명령어입니다. 우선 awk 명령어에서 구분자로 ,(쉼표)를 지정하기 위해 -F 구분자 지정 옵션에 ,를 설정합니다. awk 명령어 표현은 {}는 각 줄마다 실행하고 END {}는 마지막 줄을 읽은 다음 실행하게 됩니다. 우선 {sum += $3}으로 각 줄의 $3(세 번째 컬럼인 점수)을 변수 sum과 더합니다.
END에서 사용한 NR은 awk 내장 변수로 현재 처리한 줄 번호가 들어 있습니다. 즉 END{print sum / NR}이 실행되는 것은 마지막 줄이므로 NR에는 파일 줄 수가 들어갑니다. NR값으로 sum을 나누면 점수 평균값을 구할 수 있습니다.
점수 평균값은 앞서 확장자를 제외한 파일명에 확장자 .avg를 붙인 파일에 리다이렉트해서 출력합니다.
<주의사항>
awk에서 구분자를 쉼표로 설정할 때 -F,가 아니라 -F ',' 라고 지정해도 됩니다. 어느 쪽을 사용해도 괜찮지만 다른 사람의 코드를 읽을 때 구 가지 지정 방법이 있다는걸 기억하기 바랍니다.
이 스크립트는 값 자체에 쉼표가 포함된 CSV 파일에 대응하지 않습니다.
예제에서는 CSV 파일 내용을 확인하지 않으므로 만약 빈 파일은 0으로 나누게 되어서 에러가 발생합니다.
참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전
'IT 이야기 > Linux 셸 스크립트' 카테고리의 다른 글
[Linux 셸 스크립트] 텍스트 처리 - 076 로그 파일 컬럼 위치를 바꿔서 출력하고 보기 쉽게 바꾸기 (0) | 2021.04.12 |
---|---|
[Linux 셸 스크립트] 텍스트 처리 - 075 숫자값(CSV 파일)에서 "*"를 써서 간단한 텍스트 그래프 출력하기 (0) | 2021.04.09 |
[Linux 셸 스크립트] 텍스트 처리 - 073 CSV 파일에 ID 목록을 입력해서 대응하는 ID 컬럼값 얻기 (0) | 2021.04.08 |
[Linux 셸 스크립트] 텍스트 처리 - 072 CSV 파일에서 지정한 특정 레코드의 컬럼값 얻기 (0) | 2021.04.08 |
[Linux 셸 스크립트] 텍스트 처리 - 071 입력 파일 해시값을 줄마다 추가해서 출력하기 (0) | 2021.04.08 |
댓글