텍스트 처리 (grep·sed·awk)
4. 응용 변형 예제
4.1 압축 로그 검색 — zgrep
logrotate 가 돌린 지난 로그는 app.log.1.gz 처럼 압축돼 있습니다. 풀지 않고 zgrep 으로 바로 검색합니다.
zgrep -c ERROR app.log.*.gz # 파일별 에러 수
zcat app.log.3.gz | grep -A5 OutOfMemory # 파이프로 넘기기zcat·zless 도 같은 방식입니다. 05 로그·디스크 레슨에서 logrotate 설정과 함께 다시 봅니다.
4.2 여러 파일 한 번에 — 재귀와 xargs
설정 폴더 전체에서 DB 주소를 찾거나 바꿀 때 씁니다.
grep -rn 'db-dev' /opt/myapp/conf # 어디에 있는지
grep -rl 'db-dev' /opt/myapp/conf | xargs sed -i.bak 's/db-dev/db-prod/g'두 번째 줄은 파일 이름 목록을 sed 인자로 넘깁니다. 파일명에 공백이 있을 수 있으면 grep -rlZ 와 xargs -0 짝을 씁니다.
4.3 CSV 집계 — awk -F,
awk -F, 로 구분자를 바꾸면 CSV 도 로그와 똑같이 다룹니다.
awk -F, 'NR>1 {sum[$2]+=$3} END{for(k in sum) print k, sum[k]}' sales.csv | sort -k2 -rnNR>1 은 헤더 줄을 건너뜁니다. NR 은 현재 줄 번호, NF 는 열 개수를 담는 내장 변수입니다.
4.4 실시간 필터 — tail -f 와 grep
배포 직후 에러가 나는지 지켜볼 때 씁니다.
tail -f app.log | grep --line-buffered -E 'ERROR|WARN'--line-buffered 가 없으면 grep 이 출력을 모아 두었다가 한꺼번에 내보내 실시간으로 보이지 않습니다. 03 프로세스 레슨의 journalctl -f 도 같은 방식으로 이어집니다.
4.5 자바 스택 트레이스 묶기
한 예외가 여러 줄에 걸치므로 줄 단위 도구로는 세기 어렵습니다. awk 로 예외 첫 줄만 골라 셉니다.
awk '/^[a-z]+\.[a-zA-Z.]+(Exception|Error)/ {c[$1]++} END{for(k in c) print c[k], k}' app.log | sort -rn정규식은 java.lang.NullPointerException: 처럼 패키지 경로로 시작하는 줄을 잡습니다. at 로 시작하는 스택 줄은 조건에 걸리지 않아 제외됩니다.