리눅스 basename 명령어 사용법 - 경로에서 파일명만 뽑고 확장자 제거하기
이 명령어를 언제 쓰는가
스크립트가 파일 목록을 돌면서 "경로는 빼고 이름만" 필요할 때 쓴다. 백업 파일을 /data/backup/2026-08-25/db.sql.gz에서 읽어 로그에는 db.sql.gz만 남기거나, 원본 확장자를 떼고 새 확장자를 붙여 변환 결과 파일명을 만드는 식이다.
자기 자신의 이름을 알아내는 용도로도 흔하다. 사용법 메시지에 usage: backup.sh ...처럼 실제 실행된 이름을 찍으려면 $(basename "$0")가 가장 간단하다.
기본 형식
basename 경로 [제거할접미사]
첫 인자에서 마지막 / 뒤쪽만 남긴다. 두 번째 인자를 주면 이름 끝이 그 문자열로 끝날 때 그만큼 잘라 낸다. 접미사는 "확장자"라는 개념이 아니라 단순 문자열 매칭이므로 .tar.gz처럼 두 겹도 한 번에 뗄 수 있다.
자주 쓰는 옵션
| 옵션 | 의미 | 예시 |
|---|---|---|
| (두 번째 인자) | 해당 접미사를 제거 | basename /tmp/a.log .log → a |
| -s 접미사 | 접미사를 옵션으로 지정. 여러 경로를 함께 줄 수 있다 | basename -s .log /tmp/a.log /tmp/b.log |
| -a | 인자를 전부 경로로 취급해 한 줄에 하나씩 출력 | basename -a /tmp/a /tmp/b |
| -z | 줄바꿈 대신 NUL 구분(GNU). 공백 포함 파일명 처리용 | basename -za * |
-a와 -s는 GNU coreutils에서 왔지만 macOS·FreeBSD의 basename도 지원한다. 다만 -z는 GNU에만 있다.
실전 예제
1) 사용법 메시지에 스크립트 실제 이름을 찍는다. 심볼릭 링크로 여러 이름을 붙여 쓰는 스크립트에서 특히 유용하다.
usage() { echo "usage: $(basename "$0") [-v] 대상디렉터리" >&2; exit 2; }
2) 확장자를 바꿔 결과 파일명을 만든다. 변환 스크립트에서 가장 흔한 형태다.
for f in /data/raw/*.csv; do
name="$(basename "$f" .csv)"
gzip -c "$f" > "/data/out/${name}.csv.gz"
done
3) 두 겹 확장자를 한 번에 뗀다. 백업 파일 이름에서 날짜 부분만 남길 때 쓴다.
basename /backup/db-2026-08-25.sql.gz .sql.gz
db-2026-08-25
4) 여러 경로에서 파일명만 한꺼번에 뽑는다. 목록 비교용으로 쓴다.
basename -a /etc/nginx/conf.d/*.conf
5) 셸 내장 기능으로 대체한다. 반복문이 수천 번 돌면 외부 프로세스 호출 비용이 무시 못 할 수준이 된다.
p=/var/log/nginx/access.log
echo "${p##*/}" # access.log (basename과 동일)
echo "${p%.log}" # /var/log/nginx/access (확장자만 제거)
함정과 주의점
접미사가 이름 전체와 같으면 제거되지 않는다. basename report.txt report.txt는 빈 문자열이 아니라 report.txt를 그대로 돌려준다. 빈 이름을 만들지 않으려는 규격상 동작이다. 확장자 목록을 반복문으로 돌려 접미사를 떼는 코드에서 예상과 다른 결과가 나올 수 있다.
공백·개행이 든 파일명에서 따옴표를 빼면 깨진다. basename $f처럼 쓰면 my report.pdf가 두 인자로 쪼개져 두 번째 인자가 접미사로 해석된다. 결과가 조용히 이상해지는 유형이라 더 위험하다. 항상 basename "$f"로 감싸라.
루트와 끝 슬래시 처리를 기억하라. basename /a/b/는 끝 슬래시를 무시하고 b를, basename /는 /를 돌려준다. 파일명이 항상 비어 있지 않다고 가정한 코드가 여기서 어긋난다.
함께 보면 좋은 명령어
- dirname — 반대쪽, 즉 디렉터리 부분만 뽑는다. 거의 항상 짝으로 쓰인다.
- realpath — 상대경로를 절대경로로 고정한 뒤 basename에 넘기면 결과가 안정적이다.
- find —
-printf '%f\n'으로 basename 없이 파일명만 바로 출력할 수 있다(GNU).