이번 문서의 목표: 이 문서를 다 읽으면 로그 파일이나 설정 파일의 내용을 상황에 맞는 명령으로 확인하고, grep과 find의 자주 쓰는 옵션을 조합해 원하는 파일이나 문자열을 정확히 찾아내며, sort·wc·diff로 결과를 가공하고 비교할 수 있다.
파일 내용 읽기: cat·head·tail·more·less
07편에서 파일과 디렉터리를 다루는 법을 배웠으니, 이제 그 파일 안의 내용을 들여다보는 명령을 다룬다. 상황에 따라 어떤 명령을 골라야 할지가 시험에서도, 실무에서도 자주 갈리는 지점이다.
쉽게 말하면: 파일이 짧으면
cat, 앞부분·뒷부분만 보고 싶으면head·tail, 파일이 길어서 화면을 넘기며 봐야 하면more·less를 쓴다.
cat — 전체 내용을 한 번에 출력
cat(concatenate, 이어붙이다)은 파일 내용을 화면에 그대로 쏟아내는 명령이다.
cat [옵션] 파일명| 옵션 | 의미 |
|---|---|
-n | 모든 줄에 줄 번호를 붙여 출력 |
-b | 내용이 있는 줄에만 줄 번호를 붙여 출력(빈 줄 제외) |
-s | 여러 개의 빈 줄을 하나로 압축해 출력 |
$ cat -n memo.txt
1 회의 일정 정리
2
3 1. 월요일 오전 10시
4 2. 수요일 오후 2시cat은 이름 그대로 여러 파일을 이어붙이는 데도 쓴다. cat a.txt b.txt > merged.txt처럼 실행하면 두 파일의 내용을 순서대로 이어 붙여 merged.txt에 저장한다(재지정 기호 >의 동작은 20편에서 자세히 다룬다). 다만 파일이 화면 한 페이지보다 길면 앞부분이 스크롤되어 사라지므로, 긴 파일에는 적합하지 않다.
head, tail — 앞부분과 뒷부분만 보기
head [옵션] 파일명
tail [옵션] 파일명| 옵션 | 의미 |
|---|---|
-n 숫자 (또는 -숫자) | 기본값인 10줄 대신 지정한 줄 수만큼 출력 |
-c 숫자 | 줄이 아니라 지정한 바이트 수만큼 출력 |
-f (tail 전용) | 파일이 늘어날 때마다 새로 추가된 내용을 실시간으로 계속 출력 |
$ head -n 5 access.log
$ tail -n 5 access.logtail -f는 실무에서 로그 파일을 실시간으로 감시할 때 대표적으로 쓰는 형태다. 로그가 계속 쌓이는 파일에 tail -f access.log를 실행해 두면, 새로운 요청이 기록될 때마다 화면에 즉시 나타난다. 이 기능을 멈추려면 Ctrl + C로 강제 종료해야 한다.
more, less — 화면 단위로 넘겨 보기
파일이 화면보다 길 때, cat처럼 한 번에 쏟아내지 않고 한 화면씩 넘겨 가며 보는 명령이 more와 less다.
| 명령 | 특징 |
|---|---|
more | 앞에서 뒤로만 이동 가능(스페이스바로 다음 화면, Enter로 한 줄씩). 파일 끝에 도달하면 자동 종료 |
less | 위아래 자유 이동 가능(Page Up/Page Down, 화살표), /로 검색, q로 언제든 종료. 파일 전체를 미리 읽지 않아 큰 파일도 빠르게 열림 |
less라는 이름은 “more보다 기능이 더 많다”는 역설적인 농담에서 나왔다. 시험에서는 “앞으로만 이동 가능한 것은 more, 위아래 자유 이동과 검색이 가능한 것은 less”라는 대비를 정확히 구분하는 문제가 나온다.
자주 틀리는 점
tail -f를 “파일의 마지막 10줄만 반복 출력하는 옵션”으로 착각하는 보기가 나온다. -f(follow)는 줄 수를 지정하는 옵션이 아니라, 파일이 늘어날 때마다 새로 추가된 부분만 계속 이어서 보여 주는 실시간 감시 기능이다. 또한 more와 less를 반대로 서술해 “more는 위아래 자유 이동이 가능하다”고 낸 보기도 흔한 함정이다.
grep — 내용에서 문자열 찾기
grep(Global Regular Expression Print)은 파일 안에서 특정 문자열(또는 패턴)이 포함된 줄을 찾아 출력하는 명령이다.
grep [옵션] '찾을패턴' 파일명$ grep 'error' /var/log/messages
Mar 11 09:12:03 www kernel: disk error detected
Mar 11 09:15:41 www httpd: error in config filegrep이 자주 쓰는 옵션은 다음과 같다.
| 옵션 | 의미 |
|---|---|
-i | 대소문자 구분 없이 검색 |
-v | 패턴과 일치하지 않는 줄만 출력(반전 검색) |
-c | 일치하는 줄의 개수만 출력 |
-n | 일치한 줄의 줄 번호와 함께 출력 |
-r | 디렉터리 내부를 재귀적으로 검색 |
-l | 일치하는 줄이 있는 파일의 이름만 출력(내용은 출력하지 않음) |
-w | 단어 단위로 정확히 일치하는 경우만 검색 |
-E | 확장 정규표현식(extended regular expression) 사용 허용 |
-v 옵션은 특히 활용도가 높다. 예를 들어 설정 파일에서 주석(#으로 시작하는 줄)을 뺀 실제 설정 줄만 보고 싶을 때 다음처럼 쓴다.
$ grep -v '^#' httpd.conf^#은 정규표현식(regular expression, 문자열의 패턴을 표현하는 규칙)으로 “줄의 맨 앞(^)이 #으로 시작”함을 뜻한다. -v가 그 조건을 뒤집으므로, 결과적으로 #으로 시작하지 않는 줄만 남는다.
자주 틀리는 점
-c(개수만 출력)와 -l(파일명만 출력)을 혼동하는 보기가 자주 나온다. -c는 “일치하는 줄이 몇 개인지” 숫자를 세는 옵션이고, -l은 “여러 파일을 검색했을 때 어떤 파일에 일치하는 내용이 있었는지” 파일 이름만 나열하는 옵션이다. 둘 다 실제 내용 줄은 출력하지 않는다는 공통점 때문에 더 헷갈리기 쉽다.
find — 파일 찾기
grep이 파일의 내용을 뒤진다면, find는 파일 자체(이름·크기·권한·수정 시각 등 조건)를 뒤진다.
find [검색 시작 경로] [조건] [조치]$ find /home -name "*.txt"
/home/posein/documents/report.txt
/home/posein/memo.txt이 명령은 “/home 아래를 전부 뒤져서, 이름이 .txt로 끝나는 파일을 찾아 그 경로를 출력하라”는 뜻이다. find가 즐겨 쓰는 조건과 조치 옵션을 표로 정리하면 다음과 같다.
| 옵션 | 의미 |
|---|---|
-name '패턴' | 파일 이름이 패턴과 일치하는 것을 검색(대소문자 구분) |
-iname '패턴' | 대소문자 구분 없이 이름 검색 |
-type f | 일반 파일만 검색 |
-type d | 디렉터리만 검색 |
-type l | 심볼릭 링크만 검색 |
-user 이름 | 소유자가 특정 사용자인 것만 검색 |
-perm 모드 | 권한이 정확히 일치하는 것만 검색 |
-perm -모드 | 지정한 권한 비트를 모두 포함하는 것을 검색(이상) |
-perm /모드 | 지정한 권한 비트 중 하나라도 포함하면 검색(GNU find 확장) |
-mtime -n | 최근 n일 이내에 수정된 파일(더 최근) |
-mtime +n | 수정된 지 n일을 초과한 파일(더 오래된) |
-mtime n | 수정된 지 정확히 n일 된 파일 |
-size +n | 지정한 크기보다 큰 파일 |
-exec 명령 {} \; | 찾은 각 파일에 대해 지정한 명령을 실행 |
-perm 옵션의 부호 — 시험 단골 함정
-perm 뒤에 붙는 부호가 있는지 없는지에 따라 뜻이 완전히 달라진다는 점이 반복 출제된다.
-perm 4000: 권한이 정확히4000(그 외 비트는 전부 꺼짐)인 파일만 찾는다. 실무에서는 거의 쓸모가 없다.-perm -4000:4000비트(SetUID)가 켜져 있기만 하면 다른 비트가 무엇이든 찾아낸다. 시스템에서 SetUID가 걸린 파일을 점검할 때 실제로 쓰는 형태다.-perm /4000:4000비트가 켜진 파일을 찾되, 여러 비트를 나열했을 때 그중 하나라도 걸려 있으면 찾아낸다(GNU 확장 문법).
$ find / -user root -perm -4000이 명령은 “소유자가 root이면서 SetUID 비트가 설정된 파일을 시스템 전체에서 찾아라”는 뜻이며, 관리자가 보안 점검을 할 때 실제로 쓰는 형태다(SetUID의 동작 원리는 11편에서 다룬다).
-mtime의 부호 — 또 다른 단골 함정
-mtime도 부호에 따라 정반대의 의미가 된다.
$ find /var/log -type f -mtime +7 -name '*.log' -exec rm -f {} \;이 명령은 “/var/log 하위 전체에서, 수정된 지 7일을 초과한(+7) .log 파일을 찾아 삭제하라”는 뜻이다. 오래된 로그를 정리하는 전형적인 형태다. 만약 +7 대신 -7을 썼다면 정반대로 “최근 7일 이내에 수정된 파일”을 찾게 되어, 지우려던 오래된 파일이 아니라 방금 쌓인 최신 로그가 삭제되는 사고로 이어진다.
-exec 뒤의 {}는 찾은 파일 각각으로 치환되는 자리, 세미콜론(\;)은 -exec 명령의 끝을 셸에게 알리는 표시다(셸이 세미콜론을 자기 명령으로 해석하지 않도록 백슬래시로 이스케이프한다).
find와 xargs를 함께 쓰는 이유
find로 찾은 결과를 다른 명령에 넘길 때 -exec 대신 xargs(execute arguments, 표준 입력으로 받은 값을 다른 명령의 인자로 넘겨줌)를 쓰기도 한다. 다만 파일 이름에 공백이 들어 있으면 문제가 생길 수 있어, 이를 안전하게 처리하는 조합이 함께 출제된다.
$ find . -name "*.tmp" -print0 | xargs -0 rm-print0은 찾은 파일 이름을 줄바꿈이 아니라 널(null, 값이 없음을 나타내는 특수 문자) 문자로 구분해 출력하고, xargs -0은 그 널 문자 구분을 그대로 인식해 인자를 나눈다. 파일 이름 중간에 공백이 있어도 하나의 파일로 안전하게 인식되는 이유가 바로 이 조합 때문이다. 단순히 find ... | xargs rm처럼 줄바꿈 기준으로 넘기면, 파일 이름에 공백이 있을 때 하나의 이름이 여러 인자로 잘못 쪼개질 수 있다.
자주 틀리는 점
-perm 4000과 -perm -4000을 같은 뜻으로 착각하거나, -mtime +7과 -mtime -7을 반대로 읽는 실수가 압도적으로 많이 나온다. 부호가 없으면 “정확히 일치”, -는 “이상(포함)”, +는 시간 조건에서 “초과(더 오래됨)“라는 규칙을 예문과 함께 기억해 둔다.
sort, wc, diff — 결과 가공과 비교
sort — 줄 단위 정렬
sort [옵션] 파일명| 옵션 | 의미 |
|---|---|
-r | 역순(내림차순) 정렬 |
-n | 숫자로 인식해 정렬(문자열 순서가 아닌 실제 크기 순) |
-k 숫자 | 지정한 필드(열) 기준으로 정렬 |
-u | 정렬 결과에서 중복된 줄을 제거 |
$ sort -n scores.txt-n 옵션이 왜 필요한지가 시험 포인트다. 옵션 없이 기본 정렬을 하면 문자열 기준으로 비교하기 때문에 10이 2보다 앞에 오는(문자 1이 2보다 아스키(ASCII, 문자를 숫자로 표현하는 표준 코드) 값이 작아서) 이상한 결과가 나온다. -n을 붙여야 2, 10 순서로 실제 숫자 크기에 맞게 정렬된다.
wc — 줄·단어·글자 수 세기
wc(word count)는 파일의 줄 수, 단어 수, 바이트 수를 센다.
wc [옵션] 파일명| 옵션 | 의미 |
|---|---|
-l | 줄(line) 수만 출력 |
-w | 단어(word) 수만 출력 |
-c | 바이트(byte) 수만 출력 |
-m | 문자(character) 수만 출력(다국어 인코딩에서 바이트 수와 다를 수 있음) |
$ wc -l access.log
1523 access.log옵션 없이 wc만 실행하면 줄 수·단어 수·바이트 수 세 값을 한꺼번에 출력한다. grep과 파이프로 묶어 “특정 패턴이 몇 번 나오는지” 세는 용도로도 널리 쓴다.
$ grep -c 'error' /var/log/messages
$ grep 'error' /var/log/messages | wc -l두 명령은 결과가 같아 보이지만 미묘하게 다를 수 있다. grep -c는 일치하는 줄의 개수를 세고, grep | wc -l도 결과적으로 같은 줄 수를 세지만, 한 줄에 패턴이 여러 번 나와도 “그 줄이 걸렸는지 아닌지”만 보는 grep -c의 동작 방식은 동일하게 유지된다는 점에서 실질적으로는 같은 값이 나온다. 다만 파이프를 쓰는 방식은 grep 다음 단계에 다른 필터를 더 끼워 넣을 수 있어 확장성이 더 좋다는 차이가 있다.
diff — 두 파일 비교
diff(difference)는 두 파일의 내용을 줄 단위로 비교해 차이점을 보여 준다.
diff [옵션] 파일1 파일2$ diff old.conf new.conf
3c3
< Timeout 60
---
> Timeout 120
5a6
> LogLevel debug출력 기호의 의미는 다음과 같다.
| 기호 | 의미 |
|---|---|
숫자c숫자 | change — 해당 줄이 변경됨 |
숫자a숫자 | add — 두 번째 파일에 줄이 추가됨 |
숫자d숫자 | delete — 두 번째 파일에서 줄이 삭제됨 |
< | 첫 번째 파일(파일1) 기준의 내용 |
> | 두 번째 파일(파일2) 기준의 내용 |
위 예시에서 3c3은 “두 파일의 3번째 줄이 서로 다르다(change)“는 뜻이고, < Timeout 60은 파일1의 내용, > Timeout 120은 파일2의 내용이다. 5a6은 “파일1의 5번째 줄 다음에, 파일2에서는 6번째 줄로 LogLevel debug가 추가되었다(add)“는 뜻이다. 옵션으로 -u(unified, 통합 형식으로 표시해 앞뒤 맥락까지 함께 보여 줌)를 자주 함께 쓴다.
자주 틀리는 점
diff 출력에서 <와 >가 각각 어느 파일을 가리키는지 헷갈리는 문제가 나온다. **명령에 먼저 적은 파일이 <, 나중에 적은 파일이 >**라는 순서를 기억해야 한다. 또한 sort 없이 숫자를 정렬하면 문자열 순서로 처리되어 10이 2보다 앞선다는 점을 놓치면, -n이 왜 필요한지를 묻는 문제에서 틀리기 쉽다.
직접 해보기 1 — grep 옵션과 head·tail
00편에서 만든 Rocky Linux 컨테이너에서 진행합니다. 아직 안 만들었다면 00편을 먼저 보세요.
여러 줄짜리 연습 파일을 하나 만들고, 같은 파일에 grep 옵션을 바꿔 가며 적용해 출력이 어떻게 달라지는지, head·tail의 줄 수 지정이 어떻게 동작하는지 비교한다.
printf 'Error: disk full\nwarning: low memory\nError: timeout\nok: connected\n' > log.txt
grep -i 'error' log.txt
grep -v 'error' log.txt
grep -nc 'error' log.txt
head -n 2 log.txt
tail -n 2 log.txtprintf '...\n...'은 \n(줄바꿈)이 들어간 문자열을 그대로 출력해 한 번에 여러 줄짜리 파일을 만드는 방법이다.
무엇을 보아야 하나: -i를 빼면 Error만 걸리고 error는 안 걸리는지, -v가 정반대로(패턴이 없는 줄만) 남기는지, -c가 내용 대신 개수만 내놓는지, head -n 2·tail -n 2가 각각 파일의 앞·뒤 몇 줄을 잘라 보여주는지 확인한다.
왜 이걸 해보나:
grep -c(개수)와-l(파일명)을 헷갈리는 문제가 기출 단골이다. 옵션 하나 바꿀 때마다 출력이 달라지는 것을 직접 봐야 구분이 몸에 남는다.
직접 해보기 2 — sort의 함정과 find
sort는 옵션 없이 쓰면 문자열 순서로 정렬한다는 함정이 있다. 같은 파일로 sort와 sort -n을 비교하고, find로 방금 만든 파일을 찾아본다.
printf '10\n2\n3\n' > numbers.txt
sort numbers.txt
sort -n numbers.txt
find / -name "log.txt" 2>/dev/null2>/dev/null은 권한이 없어 뜨는 오류 메시지를 화면에서 감추는 표시다(자세한 원리는 20편).
무엇을 보아야 하나: 옵션 없는 sort에서 10이 어느 위치에 오는지, -n을 붙이면 그 위치가 어떻게 바뀌는지 비교한다. find가 / 전체를 뒤져 log.txt의 실제 경로를 출력하는지도 확인한다.
왜 이걸 해보나: 옵션 없는
sort가10을2보다 앞에 두는 것은 기출의 대표적인 함정이다. 직접 봐야 “문자열 정렬 vs 숫자 정렬”의 차이가 체감된다.
핵심 정리
- 파일 내용은 짧으면
cat, 앞뒤 일부만 보려면head/tail(-f는 실시간 추가분 감시), 화면 단위로 넘기려면more(앞으로만)·less(자유 이동·검색)를 상황에 맞게 고른다. grep은 내용 검색(-i대소문자 무시,-v반전,-c개수,-l파일명만,-r재귀),find는 파일 자체의 이름·시간·권한 조건 검색(-name,-type,-mtime,-perm)을 담당한다.find의-perm 4000(정확히 일치)·-perm -4000(포함, 이상)·-perm /4000(하나라도 포함)과,-mtime +n(초과)·-mtime -n(이내)의 부호 차이는 반드시 구분해서 외운다.sort -n은 문자열이 아닌 숫자 크기로 정렬하고,wc -l/-w/-c는 각각 줄·단어·바이트 수를 세며,diff는<(첫 번째 파일)·>(두 번째 파일) 기준으로 c(변경)·a(추가)·d(삭제)를 표시한다.