텍스트 파일은 Linux의 공통 언어입니다
Linux에서 로그, 설정 파일, 명령어 출력, CSV 같은 표 형태 데이터는 대부분 텍스트로 다룰 수 있습니다. 텍스트 파일은 종이 장부와 비슷합니다. 한 줄에 하나의 기록이 있고, 줄 안에는 날짜, 사용자, IP 주소, 상태 코드 같은 정보가 일정한 규칙으로 적혀 있습니다.
이 장의 목표는 그 장부를 눈으로 처음부터 끝까지 읽지 않는 것입니다. 필요한 줄만 찾고, 필요한 열만 뽑고, 개수를 세고, 특정 문자열을 바꾸는 방법을 익힙니다. Linux의 강점은 큰 프로그램 하나가 모든 일을 하는 데 있지 않습니다. grep, sort, uniq, wc, cut, awk, sed 같은 작은 도구를 연결해 반복적인 텍스트 작업을 빠르게 처리하는 데 있습니다.
먼저 실습 공간을 만들고 예제 파일을 준비합니다.
cd ~/linux-practice
mkdir -p text-lab
cd text-lab
cat > access.log <<'EOF'
2026-05-23 09:00:01 INFO 10.0.0.5 GET /index.html 200 512
2026-05-23 09:01:12 ERROR 10.0.0.8 POST /login 500 128
2026-05-23 09:02:33 WARN 10.0.0.5 GET /admin 403 64
2026-05-23 09:03:20 INFO 10.0.0.9 GET /index.html 200 700
2026-05-23 09:04:44 ERROR 10.0.0.8 GET /api/users 502 300
2026-05-23 09:05:10 INFO 10.0.0.10 GET /about 200 256
2026-05-23 09:06:51 ERROR 10.0.0.11 POST /login 401 100
EOF
cat > users.csv <<'EOF'
id,name,team,score
1,kim,ops,80
2,lee,dev,95
3,park,ops,70
4,choi,dev,88
EOFcat > 파일명 <<'EOF'는 여러 줄의 내용을 파일에 저장하는 방식입니다. 여기서는 실습 파일을 만들기 위해 사용합니다. 입력은 마지막 EOF 줄에서 끝납니다.
AI 생성 이미지
grep으로 필요한 줄만 찾기
grep은 파일에서 특정 문자열이나 패턴이 들어 있는 줄을 찾습니다. 두꺼운 보고서에서 형광펜으로 원하는 단어가 있는 줄만 표시하는 일과 같습니다.
가장 단순한 사용법은 다음과 같습니다.
grep ERROR access.log출력은 ERROR가 들어 있는 줄만 보여 줍니다.
2026-05-23 09:01:12 ERROR 10.0.0.8 POST /login 500 128
2026-05-23 09:04:44 ERROR 10.0.0.8 GET /api/users 502 300
2026-05-23 09:06:51 ERROR 10.0.0.11 POST /login 401 100자주 쓰는 옵션은 먼저 세 가지만 익히면 충분합니다.
grep -n ERROR access.log # 줄 번호 표시
grep -i error access.log # 대소문자 구분 없이 검색
grep -v INFO access.log # INFO가 없는 줄만 표시-n은 나중에 편집기로 해당 줄을 찾아갈 때 유용합니다. -v는 제외 조건입니다. 예를 들어 정상 로그인 INFO를 빼고 경고와 오류만 보고 싶을 때 씁니다.
정규 표현식으로 패턴 검색하기
문자열 검색은 정확히 같은 글자를 찾습니다. 정규 표현식은 "이런 모양의 글자"를 찾습니다. 예를 들어 IP 주소, 날짜, 세 자리 상태 코드처럼 값은 달라도 형태가 비슷한 데이터를 찾을 수 있습니다.
grep -E는 확장 정규 표현식을 사용합니다. 초보자는 복잡한 문법을 한 번에 외우지 말고 자주 쓰는 기호부터 익히면 됩니다.
.: 아무 문자 하나[0-9]: 숫자 하나[0-9]+: 숫자가 하나 이상 반복^: 줄의 시작$: 줄의 끝A|B: A 또는 B
오류나 경고만 찾으려면 다음처럼 씁니다.
grep -E 'ERROR|WARN' access.log날짜가 2026-05-23으로 시작하는 줄을 찾을 수도 있습니다.
grep -E '^2026-05-23' access.logIP 주소처럼 생긴 값을 포함한 줄을 찾는 예는 다음과 같습니다.
grep -E '[0-9]+.[0-9]+.[0-9]+.[0-9]+' access.log여기서 .은 실제 점 문자 .을 뜻합니다. 정규 표현식에서 그냥 .은 "아무 문자 하나"라는 특별한 뜻이 있으므로, IP 주소의 점을 찾을 때는 앞에 ``를 붙입니다.
정규 표현식은 강력하지만 처음부터 완벽하게 작성하기 어렵습니다. 중요한 습관은 한 번에 최종 명령을 만들지 않는 것입니다. 먼저 넓게 찾고, 출력 결과를 본 뒤 조건을 조금씩 좁힙니다.
wc로 줄, 단어, 바이트 세기
wc는 개수를 세는 명령입니다. 이름은 word count이지만 줄 수, 단어 수, 바이트 수도 셀 수 있습니다.
wc access.log출력은 보통 다음 순서입니다.
7 56 421 access.log왼쪽부터 줄 수, 단어 수, 바이트 수입니다. 필요한 값만 보고 싶으면 옵션을 붙입니다.
wc -l access.log # 줄 수
wc -w access.log # 단어 수
wc -c access.log # 바이트 수오류가 몇 번 발생했는지 세려면 grep 결과를 wc -l로 넘깁니다.
grep ERROR access.log | wc -l여기서 |는 앞 명령의 출력을 뒤 명령의 입력으로 보내는 연결 기호입니다. 다음 장에서 자세히 다루지만, 지금은 "앞 결과를 다음 도구에 건넨다" 정도로 이해하면 됩니다.
sort와 uniq로 정렬하고 중복 제거하기
uniq는 연속해서 반복되는 같은 줄을 하나로 줄입니다. 그래서 보통 sort로 먼저 정렬한 뒤 사용합니다. 흩어진 이름표를 가나다순으로 정리한 다음, 같은 이름표를 묶는 과정과 같습니다.
로그에서 IP 주소만 뽑아 빈도를 계산해 보겠습니다. access.log에서 IP는 네 번째 열에 있습니다.
awk '{print $4}' access.log출력은 다음과 비슷합니다.
10.0.0.5
10.0.0.8
10.0.0.5
10.0.0.9
10.0.0.8
10.0.0.10
10.0.0.11이제 정렬하고 개수를 셉니다.
awk '{print $4}' access.log | sort | uniq -c예상 출력은 다음과 같습니다.
1 10.0.0.10
1 10.0.0.11
2 10.0.0.5
2 10.0.0.8
1 10.0.0.9uniq -c는 같은 줄이 몇 번 나왔는지 앞에 개수를 붙입니다. 가장 많이 나온 IP를 위에 보고 싶으면 숫자 기준 역순 정렬을 추가합니다.
awk '{print $4}' access.log | sort | uniq -c | sort -nrsort -n은 숫자로 정렬하고, -r은 역순으로 정렬합니다. 이 방식은 접근 IP, 사용자 이름, 오류 코드처럼 반복되는 값의 빈도를 볼 때 매우 자주 쓰입니다.
cut으로 필요한 열만 뽑기
cut은 줄에서 특정 부분만 잘라 냅니다. 구분자가 일정한 파일에 특히 좋습니다. CSV 파일은 쉼표 ,로 열이 구분되어 있으므로 cut으로 다루기 쉽습니다.
cut -d ',' -f 2 users.csv옵션의 뜻은 다음과 같습니다.
-d ',': 구분자를 쉼표로 지정합니다.-f 2: 두 번째 필드를 출력합니다.
출력은 이름 열입니다.
name
kim
lee
park
choi여러 열을 뽑을 수도 있습니다.
cut -d ',' -f 2,4 users.csv이 명령은 이름과 점수 열만 출력합니다. 단, cut은 단순한 구분자 기반 도구입니다. CSV 안에 "kim, min"처럼 쉼표가 따옴표 안에 들어가는 복잡한 형식은 제대로 처리하지 못할 수 있습니다. 그런 데이터는 전용 CSV 도구나 스크립트 언어를 사용하는 편이 안전합니다.
paste로 열을 나란히 붙이기
paste는 여러 파일의 같은 줄을 옆으로 붙입니다. 두 장의 명단을 줄 번호에 맞춰 나란히 놓는 도구라고 생각하면 됩니다.
먼저 이름과 점수 파일을 따로 만들어 보겠습니다.
cut -d ',' -f 2 users.csv > names.txt
cut -d ',' -f 4 users.csv > scores.txt이제 두 파일을 붙입니다.
paste names.txt scores.txt기본 구분자는 탭입니다. 쉼표로 붙이고 싶으면 -d를 사용합니다.
paste -d ',' names.txt scores.txt출력은 다음과 같습니다.
name,score
kim,80
lee,95
park,70
choi,88paste를 사용할 때는 두 파일의 줄 순서가 서로 맞는지 먼저 확인해야 합니다. 줄이 하나라도 어긋나면 잘못된 이름과 점수가 연결됩니다.
awk로 컬럼을 읽고 계산하기
awk는 줄을 읽고, 열을 나누고, 조건에 맞는 줄을 출력하거나 계산할 수 있는 도구입니다. cut보다 똑똑한 표 계산기라고 생각하면 됩니다.
공백으로 구분된 로그에서는 $1, $2, $3처럼 열을 가리킬 수 있습니다.
awk '{print $1, $3, $4, $7}' access.log이 명령은 날짜, 로그 레벨, IP, 상태 코드를 출력합니다. access.log의 한 줄은 다음처럼 나뉩니다.
$1 날짜
$2 시간
$3 레벨
$4 IP
$5 메서드
$6 경로
$7 상태코드
$8 크기상태 코드가 500 이상인 서버 오류만 찾으려면 조건을 붙입니다.
awk '$7 >= 500 {print $1, $2, $4, $6, $7}' access.log$7 >= 500은 일곱 번째 열이 500 이상인 줄만 처리하라는 뜻입니다.
CSV처럼 구분자가 쉼표일 때는 -F로 필드 구분자를 지정합니다.
awk -F ',' '$3 == "dev" {print $2, $4}' users.csv팀이 dev인 사용자의 이름과 점수를 출력합니다.
점수 평균도 계산할 수 있습니다. 첫 줄은 헤더이므로 NR > 1 조건으로 제외합니다.
awk -F ',' 'NR > 1 {sum += $4; count += 1} END {print sum / count}' users.csv여기서 NR은 현재 줄 번호입니다. END 블록은 모든 줄을 다 읽은 뒤 한 번 실행됩니다. awk는 단순 추출을 넘어 "조건에 맞는 줄만 계산"할 때 강력합니다.
sed로 문자열을 바꾸고 줄을 고르기
sed는 stream editor의 줄임말입니다. 파일이나 입력을 줄 단위로 읽으며 문자열을 바꾸거나 특정 줄을 출력합니다. 편집기처럼 파일을 직접 열지 않고도 반복 편집을 할 수 있습니다.
가장 많이 쓰는 형태는 치환입니다.
sed 's/ERROR/FAIL/g' access.log뜻은 "각 줄에서 ERROR를 FAIL로 바꾸어 출력하라"입니다. 여기서 원본 파일은 바뀌지 않습니다. s는 substitute, 즉 치환을 뜻하고, 마지막 g는 한 줄에 여러 번 나오면 모두 바꾸라는 뜻입니다.
특정 줄 범위만 보고 싶을 때도 사용할 수 있습니다.
sed -n '2,4p' access.log-n은 자동 출력을 끄고, 2,4p는 2번 줄부터 4번 줄까지 출력하라는 뜻입니다.
파일을 직접 수정하는 sed -i는 조심해야 합니다. 실행 즉시 원본이 바뀝니다. 먼저 화면 출력으로 결과를 확인한 뒤, 백업을 만들고 적용합니다.
cp access.log access.log.bak
sed 's/ERROR/FAIL/g' access.log
sed -i 's/ERROR/FAIL/g' access.log수정 후에는 차이를 확인합니다.
diff -u access.log.bak access.log설정 파일을 다룰 때도 같은 원칙을 지킵니다. 먼저 출력으로 확인하고, 백업한 뒤, 한 가지 변경만 적용합니다.
실제 문제 해결 시나리오: 로그인 오류가 많은 IP 찾기
상황을 가정해 보겠습니다. 웹 서비스에서 로그인 실패가 늘었습니다. 로그에는 요청 경로와 상태 코드가 들어 있습니다. 목표는 /login 요청 중 오류가 많은 IP를 찾는 것입니다.
먼저 로그인 요청만 찾습니다.
grep ' /login ' access.log그다음 오류에 가까운 상태 코드를 고릅니다. 여기서는 401과 500을 봅니다.
grep ' /login ' access.log | grep -E ' 401 | 500 '이제 IP만 뽑아 빈도를 계산합니다.
grep ' /login ' access.log | grep -E ' 401 | 500 ' | awk '{print $4}' | sort | uniq -c | sort -nr출력 결과에서 개수가 큰 IP가 먼저 보입니다. 명령이 길어질수록 중간 결과를 확인하는 습관이 중요합니다. 처음부터 긴 명령을 완성하려 하지 말고 다음 순서로 점검합니다.
grep ' /login ' access.log결과가 맞는가?상태 코드 필터 후 필요한 줄만 남았는가?
awk '{print $4}'가 정말 IP 열을 출력하는가?sort | uniq -c | sort -nr결과가 빈도순인가?
이렇게 나누어 확인하면 오타나 열 번호 오류를 빨리 찾을 수 있습니다.
짧은 실습 과제
다음 명령을 직접 실행하고 출력이 왜 그렇게 나오는지 확인해 보세요.
# 1. access.log에서 403 또는 502 상태 코드가 있는 줄 찾기
grep -E ' 403 | 502 ' access.log
# 2. 로그 레벨별 개수 세기
awk '{print $3}' access.log | sort | uniq -c
# 3. users.csv에서 이름과 팀만 출력하기
cut -d ',' -f 2,3 users.csv
# 4. ops 팀의 평균 점수 계산하기
awk -F ',' '$3 == "ops" {sum += $4; count += 1} END {print sum / count}' users.csv
# 5. access.log의 INFO를 OK로 바꾼 결과를 화면에만 출력하기
sed 's/INFO/OK/g' access.log실습 중에는 원본 파일을 바로 바꾸지 않습니다. 특히 sed -i처럼 파일을 직접 수정하는 옵션은 결과를 화면으로 먼저 확인한 뒤 사용합니다.
마무리
텍스트 처리 명령은 외워서 끝나는 기술이 아닙니다. 출력 결과를 읽고, 필요한 열이 어디인지 확인하고, 작은 명령을 하나씩 연결하는 습관이 핵심입니다.
grep은 필요한 줄을 찾습니다.정규 표현식은 일정한 모양의 패턴을 찾습니다.
wc는 개수를 셉니다.sort와uniq는 정렬과 중복 제거, 빈도 계산에 씁니다.cut과paste는 단순한 열 추출과 결합에 좋습니다.awk는 컬럼 기반 조건 처리와 계산에 강합니다.sed는 문자열 치환과 줄 단위 편집에 유용합니다.
다음 장에서는 지금 사용한 |, >, >> 같은 연결 방식을 더 자세히 다룹니다. 명령어 하나의 결과를 다른 명령어의 입력으로 넘기고, 출력과 오류를 파일로 저장하는 방법을 익히면 텍스트 처리 능력이 훨씬 넓어집니다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.