파일 확장자 바꾸기

내 이 세상 도처에서 쉴 곳을 찾아보았으나, 마침내 찾아낸, 컴퓨터가 있는 구석방보다 나은 곳은 없더라.

파일 확장자 바꾸기

예전에 DOS에서는 디렉터리 안에 있는 파일의 확장자를 바꾸는 작업이 간단했다. ren(또는 rename) 명령을 사용하면 현재 디렉터리 안의 모든 *.txt 파일의 확장자를 .bak로 바꿀 수 있었다.

ren *.txt *.bak

Linux와 같은 Unix 계열 OS에서는 파일 이름을 바꿀 때 mv를 사용한다. mv는 파일이나 디렉터리를 한 곳에서 다른 곳으로 옮기는 데 사용한다. 파일 이름을 바꾸는 것도 어찌보면 파일을 옮기는 것으로 볼 수 있으므로, 이름 바꾸기에 mv를 사용한다고 해서 이상할 것은 없다.

그러나 DOS의 rename과 달리 mv는 인자를 사용하는 방식이 달라 DOS에서 하던대로 하면 에러가 발생한다.

$ mv *.txt *.bak
mv: target *.bak is not a directory

콘솔에 표시되는 메시지는 셸 버전이나 OS에 따라 차이가 있지만, 동작하지 않는 건 마찬가지다. 따라서 Unix 계열 OS에서 특정 디렉터리 안의 파일 확장자를 모두 바꾸려면 다음과 같이 간단한 스크립트를 작성해야 한다.

#!/usr/bin/env bash

for f in $(ls *.$1); do
  mv $f ${f%.$1}.$2
done

이 스크립트에서 핵심 부분은 mv의 인자 ${f%.$1}.$2다. ${parameter%pattern}의 결과는 parameter의 뒤부터 매칭되는 pattern을 삭제한 결과가 된다. 가능한 짧게 매칭되는 부분을 삭제하고 싶을 때는 %를, 가장 길게 매칭되는 부분을 삭제하고 싶을 때는 %%를 쓰면 된다.

위 스크립트를 mv-ext 파일에 저장했다면 다음과 같이 파일 확장자를 바꿀 수 있게 된다.

$ ls
a.txt b.txt

$ mv-ext txt bak

$ ls
a.bak b.bak

참고

같은 내용을 설명하는 문서지만, 예제가 포함되어 있는 Parameter Substitution이 좀더 보기 쉬웠다.