Devin.KR
로그인

리눅스 basename 명령어 사용법 - 경로에서 파일명만 뽑고 확장자 제거하기

개발자 조회 1

이 명령어를 언제 쓰는가

스크립트가 파일 목록을 돌면서 "경로는 빼고 이름만" 필요할 때 쓴다. 백업 파일을 /data/backup/2026-08-25/db.sql.gz에서 읽어 로그에는 db.sql.gz만 남기거나, 원본 확장자를 떼고 새 확장자를 붙여 변환 결과 파일명을 만드는 식이다.

자기 자신의 이름을 알아내는 용도로도 흔하다. 사용법 메시지에 usage: backup.sh ...처럼 실제 실행된 이름을 찍으려면 $(basename "$0")가 가장 간단하다.

기본 형식

basename 경로 [제거할접미사]

첫 인자에서 마지막 / 뒤쪽만 남긴다. 두 번째 인자를 주면 이름 끝이 그 문자열로 끝날 때 그만큼 잘라 낸다. 접미사는 "확장자"라는 개념이 아니라 단순 문자열 매칭이므로 .tar.gz처럼 두 겹도 한 번에 뗄 수 있다.

자주 쓰는 옵션

옵션의미예시
(두 번째 인자)해당 접미사를 제거basename /tmp/a.log .loga
-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).