[Linux] 텍스트 필터 실습

mommers·2026년 1월 30일

Linux

목록 보기
11/59


테스트 파일 만들기

# 실습 디렉터리 생성
mkdir ~/text_practice
cd ~/text_practice
# 여러 파일 생성
cat > file1.txt << EOF
TODO: Fix the login bug
Error: Connection failed
error: Database timeout
This is a normal line
TODO: Update documentation
EOF

cat > file2.txt << EOF
Function: calculateTotal()
ERROR: Memory overflow
Success: Login completed
TODO: Add error handling
EOF

cat > config.conf << EOF
# This is a comment
ServerPort=8080
# Another comment

DatabaseURL=localhost
# End of config
EOF

텍스트 필터 1. grep

  • 학습: 파일 내 특정 문자열 검색. 정규표현식 맛보기.
  • 실습:
    • 프로젝트 폴더 내 모든 파일에서 TODO 주석 찾기
      (grep -r "TODO" .).
    • 대소문자 무시(i), 줄 번호 출력(n), 매칭 안 되는 것 출력(v) 실습.
    • | grep 파이프라인 연계 연습.

실전 예제

1. "이 함수 어디에 정의돼 있지?" (프로젝트 전체 검색)

가장 많이 씀. 현재 폴더 하위의 모든 파일에서 특정 문자열을 찾음.

Bash

grep -rni "함수이름" .

  • r (Recursive): 하위 폴더까지 싹 다 뒤짐.
  • n (Line Number): 몇 번째 줄인지 알려줌.
  • i (Ignore case): 대소문자 구분 안 함 (Error, error 다 찾음).
  • .: 현재 위치에서 시작.

2. "프로세스가 죽었나 살았나?" (실행 중인 프로세스 확인)

특정 프로그램이 실행 중인지 확인할 때 사용.

Bash

ps -ef | grep "python" | grep -v "grep"
  • ps -ef: 모든 프로세스 출력.
  • | (Pipe): 앞의 결과를 grep에게 넘김.
  • grep -v "grep": 검색하고 있는 나 자신(grep 명령어)은 결과에서 뺌. (이게 꿀팁).
pi@pi-222:~/project/text_practice $ ps -ef | grep "python" | grep -v "grep"
root        1331       1  0 Jan29 ?        00:00:00 python /usr/sbin/wayvnc-control.py

3. "에러 났는데, 그 앞뒤 상황 좀 보자" (전후 문맥 확인)

로그 파일에서 "Error"만 딱 보면 원인을 모름. 에러 발생 전후 5줄을 같이 뽑아봄.

Bash

grep -C 5 "Error" file1.txt
sudo grep -C 5 "error" /var/log/syslog
sudo grep -C 5 "Failed" /var/log/auth.log
  • C 5 (Context): 해당 단어 위아래 5줄씩 같이 출력.
  • B 5 (Before): 위(이전) 5줄만.
  • A 5 (After): 아래(이후) 5줄만.

4. "주석이랑 빈 줄 다 빼고 알맹이만 줘" (설정 파일 읽기)

conf 파일이나 소스 코드에서 주석(#)과 공백을 제거하고 진짜 설정값만 보고 싶을 때.

Bash

grep -v "^#" config.conf | grep -v "^$"

  • v (Invert): 해당 패턴을 제외하고 출력.
  • ^#: #으로 시작하는 줄 (주석).
  • ^$: 아무것도 없는 줄 (빈 줄).

5. "그래서 에러가 몇 번 났는데?" (개수 세기)

로그 파일 열어서 눈으로 세지 말고 숫자로 바로 확인.

Bash

grep -c "Failed" auth.log
grep -c "Error" file1.txt
grep -c "Error" file1.txt

  • c (Count): 검색된 줄의 개수만 출력.
  • 응용: cat *.log | grep -c "Error" (모든 로그 합쳐서 에러 카운트).

텍스트 필터 2. awk, sed

  • 학습: 데이터 가공 및 치환.
  • 실습:

ls -l | awk '{print $9}'은 가장 흔하게 쓰이지만, 치명적인 약점(공백)이 있는 방법임.


ls -l 결과에서 파일명(9번째 필드)만 뽑아내기 (awk '{print $9}').

awk는 기본적으로 "공백(Space)"을 기준으로 문장을 쪼개서 $1, $2, $3...에 담음.

1. 동작 원리 (해부)

ls -l의 결과는 보통 9개의 덩어리로 이루어져 있음.

rw-r--r-- 1 root root 4096 Jan 29 20:30 my_file.txt
[ $1 ] [$2] [$3] [$4] [$5] [$6] [$7] [$8] [ $9 ]
  • $1: 권한 (rw-r--r--)
  • $3: 소유자 (root)
  • $5: 파일 크기 (4096)
  • $9: 파일 이름 (my_file.txt)

따라서 print $9를 하면 맨 뒤에 있는 파일 이름만 쏙 뽑혀 나옴.


2. 치명적인 약점 (공백이 있는 파일)

파일 이름에 띄어쓰기가 있으면 망함.

  • 파일 이름: Important Data.txt
  • 인식:
    • $9 : Important
    • $10: Data.txt
  • 결과: print $9를 하면 "Important"만 출력되고 뒤는 잘림.

3. 해결책

방법 A. AWK로 끝까지 다 찍기 (복잡)

$9부터 문장 끝($NF)까지 반복문을 돌려야 함.

Bash

ls -l | awk '{for(i=9; i<=NF; i++) printf $i " "; print ""}'

방법 B. 그냥 ls 옵션 쓰기

awk를 쓸 필요 없이, ls 자체 기능으로 이름만 출력하는 게 제일 빠르고 정확함.

Bash

ls -1

  • 숫자 1: 한 줄에 하나씩 이름만 출력하라는 옵션.
  • 공백이 있어도 완벽하게 한 줄에 하나씩 나옴.


ls -l에서 두번째 나오는 숫자의 의미

ls -l에서 두 번째 필드($2)는 "하드 링크(Hard Link)의 수"임.

쉽게 말해, "이 데이터(inode)를 가리키고 있는 이름표가 세상에 몇 개 붙어있나?"를 뜻하는 숫자.

1. 일반 파일일 때 (File)

  • 기본값: 1 (유일한 파일).
  • 의미: 파일 데이터에 접근하는 경로가 하나뿐임.
  • 숫자가 2 이상이라면?
    - 누군가 ln 명령어(하드 링크)로 이 파일에 대한 "바로가기(복제본 아님)"를 하나 더 만든 상태.
    - 이 경우, 파일 하나를 지워도 숫자가 1로 줄어들 뿐 데이터는 안 지워짐. 숫자가 0이 되어야 디스크에서 삭제됨.

2. 디렉터리(폴더)일 때 (Directory)

  • 기본값: 2 (빈 폴더일 때).
  • 왜 2인가?
    1. 부모 폴더에 있는 내 이름 (예: /home/pi)
    2. 내 폴더 안에 있는 . (자기 자신을 가리키는 점)
  • 숫자가 늘어나는 원리:
    • 이 폴더 안에 새 폴더(Sub-directory)를 만들 때마다 숫자가 1씩 증가함.
    • (새 폴더 안에 생기는 .. (부모 가리킴) 때문).

3. 활용

디렉터리의 $2 숫자를 보면 "이 안에 서브 폴더가 대충 몇 개 있는지" ls 안 해보고도 알 수 있음.

  • 공식: 링크 수 - 2 = 서브 폴더(자식 폴더) 개수

sed를 사용해 파일 내 apple 단어를 orange로 일괄 치환하여 출력 (s/old/new/g)

1. 화면에만 결과 출력 (Dry Run)

원본 파일은 건드리지 않고, "바뀌면 어떻게 될지" 미리보기만 함.

Bash

sed 's/apple/orange/g' 파일명

2. 원본 파일 덮어쓰기 (i)

확인 끝났으면 실제로 파일 내용을 변경해서 저장함.

Bash

sed -i 's/apple/orange/g' 파일명
  • i (in-place): 파일을 직접 수정하라는 핵심 옵션.

구문 해부 (s/old/new/g)

  • s (Substitute): 치환 명령.
  • g (Global): 한 줄에 apple이 여러 번 나오면 몽땅 바꿈.
    • 주의: g를 빼면 맨 처음 나온 apple 하나만 바뀌고 뒤에 건 안 바뀜.

고수들의 디테일 (\b 경계)

그냥 apple로 바꾸면 pineapplepineorange가 되는 대참사가 발생함.
정확히 단어 apple만 바꾸려면 단어 경계(Boundary)를 지정해야 함.

Bash

sed -i 's/\bapple\b/orange/g' 파일명
  • \b: 단어의 시작과 끝을 의미. (pineapple 같은 포함 단어는 제외됨).

  • CSV 파일 같은 텍스트 데이터의 특정 열만 추출하기.
profile
임베디드 개발자가 되기 위해 공부중입니다!

0개의 댓글