iBetter Books
수정

명령어 조합 실습

이제 앞서 배운 명령어들을 실전 상황에서 조합해봅시다. 단계별로 명령어를 쌓아가는 방식으로 풀이합니다. 처음부터 완성된 파이프라인을 외울 필요는 없습니다. "이 결과에서 저게 필요하다"는 생각을 이어가다 보면 자연스럽게 파이프라인이 완성됩니다.

실습 1 — 로그 파일에서 에러만 추출하기

서버 로그에서 ERROR 메시지만 골라내 별도 파일로 저장하는 상황입니다.

# 1단계: 로그 파일 내용 확인head -20 /var/log/syslog
Apr 24 08:00:01 ubuntu-server systemd[1]: Started Daily apt.
Apr 24 08:05:23 ubuntu-server kernel: ERROR disk I/O timeout
Apr 24 08:10:00 ubuntu-server sshd[1234]: Accepted publickey
Apr 24 08:10:01 ubuntu-server kernel: ERROR unable to mount
# 2단계: ERROR가 포함된 줄만 필터링grep "ERROR" /var/log/syslog
Apr 24 08:05:23 ubuntu-server kernel: ERROR disk I/O timeout
Apr 24 08:10:01 ubuntu-server kernel: ERROR unable to mount
Apr 24 09:15:44 ubuntu-server app[5678]: ERROR database connection failed
# 3단계: 오늘 날짜 것만 추리기 (날짜 형식: Apr 24)grep "ERROR" /var/log/syslog | grep "$(date '+%b %e')"
Apr 24 08:05:23 ubuntu-server kernel: ERROR disk I/O timeout
Apr 24 08:10:01 ubuntu-server kernel: ERROR unable to mount
Apr 24 09:15:44 ubuntu-server app[5678]: ERROR database connection failed
# 4단계: 결과를 파일로 저장하면서 개수도 확인grep "ERROR" /var/log/syslog \  | grep "$(date '+%b %e')" \  | tee today_errors.txt \  | wc -l
3

today_errors.txt에는 오늘의 ERROR 로그가 저장되고, 화면에는 총 3건임을 알려줍니다.

실습 2 — 디렉토리별 파일 크기 합산하기

홈 디렉토리에서 각 서브디렉토리의 용량을 큰 순서로 정렬하는 상황입니다.

# 1단계: 각 디렉토리 용량 확인du -sh ~/*/
512M	/home/ubuntu/Downloads/
 24M	/home/ubuntu/Documents/
4.0K	/home/ubuntu/scripts/
 1.2G	/home/ubuntu/projects/
# 2단계: 숫자로 정렬 가능한 형식 사용du -s ~/*/
524288	/home/ubuntu/Downloads/
 24576	/home/ubuntu/Documents/
  4096	/home/ubuntu/scripts/
1258291	/home/ubuntu/projects/
# 3단계: 크기 내림차순 정렬du -s ~/*/ | sort -rn
1258291	/home/ubuntu/projects/
 524288	/home/ubuntu/Downloads/
  24576	/home/ubuntu/Documents/
   4096	/home/ubuntu/scripts/
# 4단계: 읽기 쉬운 형식으로 다시 표시 (상위 5개)du -sh ~/*/ | sort -rh | head -5
1.2G	/home/ubuntu/projects/
512M	/home/ubuntu/Downloads/
 24M	/home/ubuntu/Documents/
4.0K	/home/ubuntu/scripts/

sort -h는 사람이 읽기 좋은 형식(K, M, G)을 비교할 때 사용하는 옵션입니다.

실습 3 — 특정 확장자 파일 개수 세기

프로젝트 디렉토리에서 언어별 소스 파일이 몇 개인지 확인하는 상황입니다.

# 1단계: .sh 파일 모두 찾기find ~/projects -name "*.sh" -type f
/home/ubuntu/projects/bash/scripts/backup.sh
/home/ubuntu/projects/bash/scripts/deploy.sh
/home/ubuntu/projects/bash/monitor.sh
# 2단계: 개수만 세기find ~/projects -name "*.sh" -type f | wc -l
3
# 3단계: 여러 확장자를 한 번에 비교for ext in sh py js txt; do    count=$(find ~/projects -name "*.$ext" -type f | wc -l)    echo "$ext: $count 개"done
sh: 3 개
py: 12 개
js: 8 개
txt: 5 개
# 4단계: 가장 많은 확장자 순으로 정렬for ext in sh py js txt md; do    count=$(find ~/projects -name "*.$ext" -type f 2>/dev/null | wc -l)    printf "%5d %s\n" "$count" "$ext"done | sort -rn
   12 py
    8 js
    5 txt
    3 sh
    1 md

실습 4 — 프로세스 목록에서 특정 프로세스 찾기

현재 실행 중인 Python 프로세스를 찾고 메모리 사용량을 확인하는 상황입니다.

# 1단계: 전체 프로세스 목록ps aux | head -5
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 168608 11264 ?        Ss   Apr23   0:03 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Apr23   0:00 [kthreadd]
ubuntu    1234  0.5  2.3 512000 48000 ?        Sl   08:00   0:30 python3 app.py
ubuntu    1235  0.1  1.5 256000 31000 ?        S    08:00   0:05 python3 worker.py
# 2단계: python 프로세스만 필터링ps aux | grep python
ubuntu    1234  0.5  2.3 512000 48000 ?        Sl   08:00   0:30 python3 app.py
ubuntu    1235  0.1  1.5 256000 31000 ?        S    08:00   0:05 python3 worker.py
ubuntu    9999  0.0  0.0   6432   724 pts/0    S+   09:30   0:00 grep python
# 3단계: grep 자신을 결과에서 제외ps aux | grep python | grep -v grep
ubuntu    1234  0.5  2.3 512000 48000 ?        Sl   08:00   0:30 python3 app.py
ubuntu    1235  0.1  1.5 256000 31000 ?        S    08:00   0:05 python3 worker.py
# 4단계: PID만 추출ps aux | grep python | grep -v grep | awk '{print $2}'
1234
1235
# 5단계: 메모리 사용량 순으로 정렬하여 상위 5개ps aux | grep python | grep -v grep | sort -k4 -rn | head -5
ubuntu    1234  0.5  2.3 512000 48000 ?        Sl   08:00   0:30 python3 app.py
ubuntu    1235  0.1  1.5 256000 31000 ?        S    08:00   0:05 python3 worker.py

sort -k4는 4번째 컬럼(메모리 %)을 기준으로 정렬합니다.

실습 5 — 중복 파일 찾기

같은 크기의 파일을 찾아 중복 여부를 확인하는 상황입니다.

# 1단계: 파일 크기와 경로 목록 만들기find ~/projects -type f | xargs ls -l 2>/dev/null | awk '{print $5, $9}' | sort
   0 /home/ubuntu/projects/empty1.txt
   0 /home/ubuntu/projects/empty2.txt
1024 /home/ubuntu/projects/bash/backup.sh
1024 /home/ubuntu/projects/bash/backup_copy.sh
4096 /home/ubuntu/projects/large_file.bin
# 2단계: 크기가 같은 파일 찾기 (크기 기준으로 중복된 줄)find ~/projects -type f -not -empty \  | xargs ls -l 2>/dev/null \  | awk '{print $5, $9}' \  | sort \  | awk '{print $1}' \  | uniq -d
0
1024
# 3단계: 해시로 실제 내용이 같은 파일 확인find ~/projects -type f | xargs md5sum 2>/dev/null | sort | awk '{print $1}' | uniq -d
d41d8cd98f00b204e9800998ecf8427e
a3c1e5c84a56a9e8432f20f6c3b7e1f9
# 4단계: 중복 파일 목록 전체 보기find ~/projects -type f | xargs md5sum 2>/dev/null \  | sort \  | uniq -w32 -D
d41d8cd98f00b204e9800998ecf8427e  /home/ubuntu/projects/empty1.txt
d41d8cd98f00b204e9800998ecf8427e  /home/ubuntu/projects/empty2.txt
a3c1e5c84a56a9e8432f20f6c3b7e1f9  /home/ubuntu/projects/bash/backup.sh
a3c1e5c84a56a9e8432f20f6c3b7e1f9  /home/ubuntu/projects/bash/backup_copy.sh

uniq -w32는 처음 32자(md5 해시)만 비교하고, -D는 중복된 모든 줄을 출력합니다.

실습 정리 — 파이프라인 설계 원칙

다섯 가지 실습을 통해 공통된 패턴을 확인할 수 있습니다.

  1. 먼저 데이터를 가져옵니다. (find, ps, ls, cat 등)
  2. 필요한 것만 걸러냅니다. (grep, awk, sed)
  3. 정렬하거나 중복을 제거합니다. (sort, uniq)
  4. 집계하거나 변환합니다. (wc, awk, cut)
  5. 결과를 저장하거나 출력합니다. (tee, >, 화면)

복잡한 파이프라인을 한 번에 완성하려 하지 말고, 단계를 하나씩 추가하면서 결과를 확인하는 방식으로 작업하면 실수를 줄일 수 있습니다. 다음 파트에서는 이 명령어들을 스크립트 파일에 담아 자동화하는 방법을 배웁니다.