728x90
문제 31. reverse-me.txt 파일의 줄 순서를 뒤집어 마지막 줄이 먼저 출력되도록 하시오.
💡 힌트 보기
줄 순서를 뒤집는 명령어가 있습니다.
tac은 cat의 반대 동작을 합니다.
tac reverse-me.txt
📖 왜 이렇게 쓸까?
tac은cat을 거꾸로 뒤집은 이름으로, 파일의 줄 순서를 역순으로 출력합니다.cat이 첫 줄부터 마지막 줄 순으로 출력한다면,tac은 마지막 줄부터 첫 줄 순으로 출력합니다.tail -r이나awk로도 구현할 수 있지만tac이 가장 간결합니다.
문제 32. faces.txt 파일에서 중복된 줄을 제거하되, 첫 번째 등장한 줄만 남기고 순서를 유지하여 출력하시오.
💡 힌트 보기
awk를 사용하면 줄을 기억해두면서 한 번 본 줄은 건너뛰는 방식으로 순서를 유지한 채 중복을 제거할 수 있습니다.
awk '!seen[$0]++' faces.txt
📖 왜 이렇게 쓸까?
seen[$0]은 현재 줄을 키로 사용하는 연관 배열로, 해당 줄이 등장한 횟수를 기록합니다.!를 앞에 붙이면 처음 등장하는 줄(값이 0일 때)만 출력합니다.sort | uniq와 달리 정렬 없이 원래 순서를 유지하므로 이 문제에 적합합니다.
문제 33. random-numbers.txt에는 100개의 정수가 있습니다. 파일에서 유일한 소수(prime number)의 개수를 출력하시오.
💡 힌트 보기
소수 판별은 쉘 명령어만으로 어렵습니다.
factor 명령어를 활용하면 각 숫자의 인수를 확인할 수 있습니다.
sort -un random-numbers.txt | while read n; do
factors=$(factor $n | tr -s ' ' | cut -d' ' -f2-)
[ "$factors" = "$n" ] && echo $n
done | wc -l
📖 왜 이렇게 쓸까?
factor n은 숫자n의 소인수를 출력합니다. 소수는 자기 자신만 인수로 갖습니다.sort -un으로 먼저 중복을 제거하고 숫자 정렬을 합니다.- 인수가 자기 자신 하나뿐이면 소수이므로, 그런 경우에만 출력하고
wc -l로 개수를 셉니다.
문제 34. access.log.1과 access.log.2 두 파일에 공통으로 존재하는 IP 주소를 한 줄에 하나씩 출력하시오.
💡 힌트 보기
두 파일의 교집합을 구할 때는
comm 명령어를 사용할 수 있습니다. 단, 입력이 정렬되어 있어야 합니다.
comm -12 \
<(grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log.1 | sort -u) \
<(grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log.2 | sort -u)
📖 왜 이렇게 쓸까?
grep -oE로 각 파일에서 IP 주소 패턴만 추출하고sort -u로 중복을 제거합니다.comm -12는 두 정렬된 입력에서 공통 줄만 출력합니다. (-1은 첫 번째 파일 고유 줄 숨김,-2는 두 번째 파일 고유 줄 숨김)<(...)는 프로세스 치환(Process Substitution)으로, 명령어 결과를 파일처럼 전달합니다.
문제 35. "access.log"로 시작하는 모든 파일에서 다음 줄에 "404"가 포함된 줄을 파일명 없이 출력하시오. (재귀 탐색)
💡 힌트 보기
grep의 -A 옵션은 매칭된 줄의 다음 줄도 함께 출력합니다. 여러 옵션을 조합해 보세요.
find . -name "access.log*" | xargs grep -h -A1 "" | grep -B1 "404" | grep -v "404" | grep -v "^--$"
📖 왜 이렇게 쓸까?
grep -A1은 매칭된 줄과 그 다음 줄 1개를 함께 출력합니다.grep -B1 "404"는 "404"가 있는 줄과 그 이전 줄을 함께 출력합니다.- 두 번의
grep을 조합해 "다음 줄에 404가 있는 줄"만 추려내고,grep -v로 404 줄 자체와 구분선(--)을 제거합니다.
문제 36. 현재 디렉토리에서 base.bin과 내용이 다른 .bin 확장자 파일을 모두 출력하시오.
💡 힌트 보기
두 파일을 비교할 때는
diff 또는 cmp 명령어를 사용할 수 있습니다.
find . -maxdepth 1 -name "*.bin" ! -name "base.bin" | while read f; do
cmp -s "$f" base.bin || echo "$f"
done
📖 왜 이렇게 쓸까?
cmp -s는 두 파일을 조용히 비교하여 다르면 종료 코드 1을 반환합니다.||는 앞 명령이 실패(파일이 다름)할 때만 뒤 명령을 실행하므로, 다른 파일명만 출력됩니다.! -name "base.bin"으로 비교 기준 파일 자체는 탐색에서 제외합니다.
문제 37. ./.../ /. .the flag.txt 경로에 있는 파일의 내용을 출력하시오.
💡 힌트 보기
공백과 점이 포함된 특수한 경로는 따옴표나 이스케이프 처리가 필요합니다.

cat './.../ /. .the flag.txt'
📖 왜 이렇게 쓸까?
- 공백이 포함된 경로는 쉘이 여러 인자로 분리해서 해석하므로, 반드시 따옴표로 감싸야 합니다.
...처럼 점으로 시작하는 디렉토리 이름도 유효한 경로이며, 따옴표 안에서는 그대로 사용할 수 있습니다.- 이스케이프 처리(
\)로도 공백을 처리할 수 있지만, 전체를 따옴표로 감싸는 방법이 더 직관적입니다.
문제 38. file-with-tabs.txt에서 탭 문자가 포함된 줄의 수를 출력하시오.
💡 힌트 보기
탭 문자는
\t로 표현됩니다. grep에서 탭 문자를 검색하는 방법을 생각해 보세요.
grep -cP '\t' file-with-tabs.txt
📖 왜 이렇게 쓸까?
grep -P는 Perl 호환 정규 표현식(PCRE)을 사용할 수 있게 해줍니다.\t는 탭 문자를 나타내는 이스케이프 시퀀스로,-P옵션 없이는 인식되지 않습니다.-c옵션은 매칭된 줄의 수만 출력하므로 별도의wc -l없이 바로 개수를 얻을 수 있습니다.
문제 39. 현재 작업 디렉토리에서 .txt와 .exe 확장자가 아닌 파일을 재귀적으로 모두 삭제하시오.
💡 힌트 보기
find의 !와 -name을 조합하면 특정 확장자를 제외한 파일을 찾을 수 있습니다.
find . -type f ! -name "*.txt" ! -name "*.exe" -delete
📖 왜 이렇게 쓸까?
! -name "*.txt"는.txt가 아닌 파일만 선택하는 부정 조건입니다.- 두 조건을 모두 붙이면
.txt도 아니고.exe도 아닌 파일만 대상이 됩니다. -delete로 해당 파일을 즉시 삭제하며, 실행 전-delete없이 먼저 목록을 확인하는 것이 안전합니다.
문제 40. 현재 디렉토리에서 파일명이 대시(-)로 시작하는 파일을 모두 삭제하시오.
💡 힌트 보기
대시로 시작하는 파일명은 명령어 옵션으로 해석될 수 있습니다.
--나 ./를 앞에 붙여서 파일명임을 명시해 보세요.
find . -maxdepth 1 -name '-*' -delete
📖 왜 이렇게 쓸까?
rm -*는 대시를 옵션으로 해석하므로 오류가 발생합니다.find를 사용하면 이 문제를 우회할 수 있습니다.-name '-*'는 대시로 시작하는 파일명만 매칭합니다.rm -- -filename처럼--를 사용하는 방법도 있으며, 이는 이후 인자를 옵션이 아닌 파일명으로 처리하도록 강제합니다.
문제 41. ps-ef1과 ps-ef2 두 파일의 내용을 PID 기준으로 정렬하고 중복 줄을 제거하여 출력하시오.
💡 힌트 보기
두 파일을 합치고 특정 컬럼 기준으로 정렬할 때
sort의 -k 옵션을 활용할 수 있습니다.
cat ps-ef1 ps-ef2 | sort -u -k2 -n
📖 왜 이렇게 쓸까?
cat으로 두 파일을 하나로 합칩니다.sort -k2는 두 번째 필드(PID 컬럼)를 기준으로 정렬하며,-n은 숫자 순서로 정렬합니다.-u옵션은 중복 줄을 제거합니다. 정렬과 중복 제거를 한 번에 처리할 수 있습니다.
문제 42. netstat.out 파일에서 IPv4 리스닝 포트를 높은 번호부터 낮은 번호 순으로 출력하시오.
💡 힌트 보기
grep으로 LISTEN 상태의 줄을 필터링하고, awk로 포트 번호를 추출한 뒤 역순 정렬해 보세요.
grep -E 'LISTEN' netstat.out | grep -v ':::' | awk '{print $4}' | awk -F: '{print $NF}' | sort -rn | uniq
📖 왜 이렇게 쓸까?
grep 'LISTEN'으로 리스닝 상태의 줄만 추출하고,grep -v ':::'로 IPv6 주소를 제외합니다.awk '{print $4}'로 로컬 주소 컬럼을 추출한 뒤,-F: '{print $NF}'로 콜론 뒤 포트 번호만 가져옵니다.sort -rn은 숫자를 내림차순(-r) 정렬하며,uniq로 중복 포트를 제거합니다.
728x90
'Linux > Hands-on Practice' 카테고리의 다른 글
| Command Challenge | 21~30번 문제 정답 및 해설 (0) | 2026.05.17 |
|---|---|
| Command Challenge | 11~20번 문제 정답 및 해설 (0) | 2026.05.17 |
| Command Challenge | 1~10번 문제 정답 및 해설 (0) | 2025.09.22 |
| 리눅스 명령어 학습 및 테스트 사이트 소개 (0) | 2025.09.21 |
