리눅스 sort 명령어 사용법 - 숫자 정렬, 컬럼 정렬 옵션과 실전 예제
이 명령어를 언제 쓰는가
로그를 분석할 때 가장 알고 싶은 것은 대개 "무엇이 가장 많은가"다. 어느 IP가 제일 많이 붙었는지, 어느 URL이 제일 많이 500을 냈는지. 이 계산의 중심에 sort 가 있다. sort | uniq -c | sort -rn 은 리눅스 텍스트 처리에서 가장 자주 쓰이는 세 줄 관용구다.
uniq 가 인접한 줄만 비교하기 때문에, 중복을 제거하거나 세려면 반드시 먼저 정렬해야 한다는 점도 sort 를 자주 쓰게 되는 이유다.
기본 형식
sort [옵션] 파일...
옵션이 없으면 사전순(문자열 비교)으로 오름차순 정렬한다. 파일명을 생략하면 표준 입력을 읽는다.
자주 쓰는 옵션
| 옵션 | 의미 | 예시 |
|---|---|---|
-n | 숫자로 비교한다. 사전순 문제를 없앤다 | sort -n sizes.txt |
-r | 내림차순으로 뒤집는다 | sort -rn counts.txt |
-k N | N번째 필드를 기준으로 정렬한다 | sort -k 2 data.txt |
-t 문자 | 필드 구분자를 지정한다 (기본은 공백) | sort -t: -k3 -n /etc/passwd |
-u | 정렬하면서 중복을 제거한다 | sort -u emails.txt |
-h | 1K, 2.3G 같은 사람이 읽는 크기를 정렬한다 (POSIX 아님. GNU·macOS 는 지원, busybox 는 없음) | du -h | sort -h |
-V | 버전 번호를 자연스럽게 정렬한다 (POSIX 아님. GNU·macOS 는 지원, busybox 는 없음) | sort -V versions.txt |
-o 파일 | 결과를 파일에 쓴다. 입력 파일과 같아도 안전하다 | sort -o list.txt list.txt |
-f | 대소문자를 무시하고 비교한다 | sort -f names.txt |
실전 예제
1) 접속이 가장 많은 IP 상위 10개를 뽑는다. 이상 트래픽을 확인하는 첫 명령이다.
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -n 10
출력은 이런 형태다. 왼쪽이 건수, 오른쪽이 값이다.
48211 203.0.113.42
10394 198.51.100.7
2205 192.0.2.19
2) 용량을 많이 먹는 디렉터리 순으로 본다. 디스크가 찼을 때 쓰는 조합이다.
du -sh /var/* 2>/dev/null | sort -h
-h 가 없으면 9.8G 가 512M 보다 작게 정렬된다.
3) 콜론으로 구분된 파일을 세 번째 컬럼 기준으로 정렬한다. UID 순으로 계정을 보는 경우다.
sort -t: -k3 -n /etc/passwd
4) 두 파일의 차이를 비교한다. 배포 전후 파일 목록을 대조하는 식으로 쓴다.
sort before.txt > /tmp/a.txt
sort after.txt > /tmp/b.txt
diff /tmp/a.txt /tmp/b.txt
5) 중복을 제거한 유일한 값 목록을 만든다. 메일 발송 대상 명단 정리 같은 작업이다.
sort -u emails.txt > emails-uniq.txt
6) 여러 키로 정렬한다. 부서별로 묶고 그 안에서 급여 내림차순으로 보는 경우다.
sort -t, -k1,1 -k3,3rn employees.csv
함정과 주의점
기본 정렬은 사전순이라 숫자가 뒤죽박죽 나온다. 가장 많이 데는 지점이다.
$ printf '2\n10\n9\n' | sort
10
2
9
문자열로 비교하니 1 이 2 보다 앞이라 10이 맨 위에 온다. 숫자 컬럼은 반드시 -n 을 붙인다.
sort file > file 은 파일을 0바이트로 만든다. 셸이 sort 를 실행하기 전에 리다이렉션 대상을 먼저 비우기 때문이다. 제자리 정렬은 -o 를 쓴다. sort 는 -o 대상이 입력과 같은 경우를 알고 안전하게 처리한다.
sort -o list.txt list.txt # 안전
sort list.txt > list.txt # 파일이 사라진다
-k2 는 "2번째 필드"가 아니라 "2번째 필드부터 줄 끝까지"다. 그래서 -k2 -n 을 줬는데 결과가 이상한 경우가 생긴다. 딱 그 필드만 쓰려면 시작과 끝을 함께 지정한다.
sort -t, -k3,3 -n data.csv # 3번째 필드만 숫자로 비교
로케일에 따라 정렬 결과가 달라진다. ko_KR.UTF-8 환경과 C 환경은 대소문자·특수문자 처리 순서가 다르다. 개발 PC와 서버의 정렬 결과가 안 맞아 스크립트가 깨지는 일이 실제로 있다. 재현 가능한 결과가 필요하면 로케일을 고정한다.
LC_ALL=C sort data.txt
join, comm, uniq 같은 명령과 조합할 때는 이 고정이 사실상 필수다.
대용량 파일 정렬은 메모리와 /tmp 를 쓴다. 수 GB 파일을 정렬하면 임시 파일이 /tmp 에 쌓여 디스크가 찰 수 있다. sort -T /data/tmp 로 작업 디렉터리를 바꾸거나 -S 1G 로 메모리 사용량을 조절한다.
함께 보면 좋은 명령어
- uniq — sort 의 짝. 정렬된 입력에서 중복을 제거하거나 센다.
- awk — 정렬할 컬럼만 먼저 뽑아내면 sort 가 훨씬 가벼워진다.
- comm — 정렬된 두 파일의 공통/차집합을 줄 단위로 비교한다.