sort와 uniq
"가장 많이 접속한 IP는 어디일까?" 이 질문에 답하려면 IP를 모아서, 세어서, 순서대로 정렬해야 합니다. sort와 uniq가 그 역할을 합니다.
sort는 줄을 정렬하고, uniq는 연속된 중복 줄을 처리합니다. 둘을 파이프로 연결하면 데이터 빈도 분석이라는 강력한 패턴이 만들어집니다.
sort 기본 사용법
sort 파일명sort 옵션 파일명명령어 | sort 옵션
샘플 데이터를 먼저 만들겠습니다.
# 새 파일: /tmp/scores.txtcat > /tmp/scores.txt << 'EOF'김철수 85이영희 92박민준 78최수진 92정대현 65강지연 88윤서준 78임채원 95EOF
# 기본 정렬 (알파벳/사전 순)sort /tmp/scores.txt
강지연 88
김철수 85
박민준 78
윤서준 78
이영희 92
임채원 95
정대현 65
최수진 92
sort 주요 옵션
| 옵션 | 설명 | 예시 |
|---|---|---|
-n |
숫자 순서로 정렬 | sort -n scores.txt |
-r |
역순으로 정렬 | sort -r scores.txt |
-k N |
N번째 필드 기준으로 정렬 | sort -k 2 scores.txt |
-t 구분자 |
필드 구분자 지정 | sort -t: -k 3 /etc/passwd |
-u |
정렬 후 중복 제거 | sort -u names.txt |
-h |
사람이 읽기 좋은 수 정렬 (1K, 2M 등) | du -sh * | sort -h |
-f |
대소문자 구분 없이 정렬 | sort -f words.txt |
# 점수(2번째 필드)를 숫자 순으로 정렬sort -k 2 -n /tmp/scores.txt
정대현 65
박민준 78
윤서준 78
김철수 85
강지연 88
이영희 92
최수진 92
임채원 95
# 점수 내림차순 (높은 점수 먼저)sort -k 2 -n -r /tmp/scores.txt
임채원 95
이영희 92
최수진 92
강지연 88
김철수 85
박민준 78
윤서준 78
정대현 65
# 파일 크기 정렬 (인간 친화적)du -sh /tmp/* 2>/dev/null | sort -h | head -5
uniq 기본 사용법
uniq는 연속된 중복 줄을 처리합니다. 반드시 sort를 먼저 해야 전체 중복을 제거할 수 있습니다.
# 새 파일: /tmp/ips.txtcat > /tmp/ips.txt << 'EOF'192.168.1.110.0.0.5192.168.1.210.0.0.5192.168.1.1192.168.1.310.0.0.5192.168.1.1192.168.1.410.0.0.5EOF
# sort 없이 uniq 사용 (연속 중복만 제거)uniq /tmp/ips.txt
192.168.1.1
10.0.0.5
192.168.1.2
10.0.0.5
192.168.1.1
192.168.1.3
10.0.0.5
192.168.1.1
192.168.1.4
10.0.0.5
연속하지 않은 중복은 제거되지 않았습니다.
# sort 후 uniq (완전한 중복 제거)sort /tmp/ips.txt | uniq
10.0.0.5
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
uniq 주요 옵션
| 옵션 | 설명 |
|---|---|
-c |
각 줄이 몇 번 나왔는지 앞에 표시 |
-d |
중복된 줄만 출력 |
-u |
딱 한 번만 나온 줄만 출력 |
# 각 IP가 몇 번 등장했는지 세기sort /tmp/ips.txt | uniq -c
4 10.0.0.5
3 192.168.1.1
1 192.168.1.2
1 192.168.1.3
1 192.168.1.4
빈도 분석 패턴: sort | uniq -c | sort -rn
이 세 단계 파이프라인은 매우 자주 쓰입니다. "어떤 것이 가장 많이 나왔는가"를 빠르게 분석합니다.
sort /tmp/ips.txt | uniq -c | sort -rn
4 10.0.0.5
3 192.168.1.1
1 192.168.1.4
1 192.168.1.3
1 192.168.1.2
가장 많이 등장한 순서로 정렬되었습니다.
실습: 로그에서 가장 많이 접속한 IP 찾기
앞 절에서 만든 access.log를 분석합니다.
# access.log에서 IP 주소(첫 번째 필드) 추출 후 빈도 분석cut -d' ' -f1 /tmp/access.log | sort | uniq -c | sort -rn
4 10.0.0.5
3 192.168.1.1
2 192.168.1.2
1 192.168.1.4
1 192.168.1.3
cut 명령어는 다음 절에서 자세히 배웁니다. 여기서는 -f1이 첫 번째 필드(IP 주소)를 뽑는다는 것만 기억합니다.
# 실습: HTTP 상태 코드별 요청 수 집계cut -d'"' -f3 /tmp/access.log | cut -d' ' -f2 | sort | uniq -c | sort -rn
6 200
2 500
1 404
1 403
1 401
정상 응답(200)이 6건, 서버 오류(500)가 2건입니다.
# 실습: CSV 파일에서 특정 열 정렬cat > /tmp/products.csv << 'EOF'상품명,카테고리,가격노트북,전자기기,1200000마우스,전자기기,35000키보드,전자기기,89000책상,가구,450000의자,가구,320000모니터,전자기기,680000EOF# 카테고리(2열) 기준으로 정렬, 헤더는 제외tail -n +2 /tmp/products.csv | sort -t',' -k2
책상,가구,450000
의자,가구,320000
노트북,전자기기,1200000
마우스,전자기기,35000
키보드,전자기기,89000
모니터,전자기기,680000
-t','로 쉼표를 구분자로 지정하고, -k2로 두 번째 필드 기준으로 정렬했습니다.