([a-z]+)-([0-9]+).([a-z]+) 형식의 파일 이름을 일괄적으로 바꾸기

lqez의 이미지

몇 년이 지나도 여전한 리눅스 초보입니다.

파일 이름이 0-padding이 안되어, a-99.jpg, a-101.jpg, a-1000.jpg와 같이 되어 있을 때,
일괄적으로 a-xxxxx.jpg로 바꾸는 좋은 방법이 없을까요? 전 일단 awk를 써서 아래와 같이 해봤는데 별로 아름답지는 않네요.

ls *.jpg | awk '{ split( $1, pre, "-" ); split( pre[2], fn, "." ); printf( "mv \"%s\" \"%s-%05d.%s\"\n", $1, pre[1], fn[1], fn[2] ) }' | /bin/sh

aero의 이미지

Perl로 해보면

ls *.jpg | perl -nle 'system "mv $_ ".do { s/\d+/sprintf("%05d",$&)/e; $_ }'

Perl이 설치된 시스템이면 기본적으로 Perl로된 rename 명령이 설치되어 있는데
그걸 사용하면 위에서 정규식부분만 가져와서 다음과 같이 하면 됩니다.

rename 's/\d+/sprintf("%05d",$&)/e' *.jpg

정규식 s/\d+/sprintf("%05d",$&)/e 을 설명드리자면
숫자인 부분을 찾아서(파일명 조건에서 숫자인 부분은 명확하므로 특별히 앞뒤 조건은 안따짐)
포멧된 문자열을 리턴하는 sprintf문을 써서 Perl에서 정규식에서 매칭된 부분을 뜻하는 $&(여기서는 숫자)
를 특정포멧(%05d)으로 찍는 코드를 정규식 뒤에 e modifier로 실행시켜서 그 값으로 대치하라는 의미입니다.

rename 명령은 일단 실행되기전에 적용한 패턴이 잘 맞는지 테스트만 해보려면 -n 옵션을 줘서
다음처럼 하면 됩니다. 테스트 해보고 원하는 형태면 -n 옵션을 빼고 적용시키면 되겠지요

$ rename -n 's/\d+/sprintf("%05d",$&)/e' *.jpg
a-1000.jpg renamed as a-01000.jpg
a-101.jpg renamed as a-00101.jpg
a-99.jpg renamed as a-00099.jpg
auditory의 이미지

rename 관련해서 저는 자주 헷갈리는것이
동일한 이름의 두가지 버전의 rename이 있습니다.
앞서 말씀하신 perl 버전이 있고요..
다른 버전도 있습니다..
이 버전에 대해서 man rename 해보니 아래와 같이 나오네요..

       rename  will  rename  the specified files by replacing the first occurrence of from in their
       name by to.
 
       For example, given the files foo1, ..., foo9, foo10, ..., foo278, the commands
 
              rename foo foo0 foo?
              rename foo foo0 foo??
 
       will turn them into foo001, ..., foo009, foo010, ..., foo278.
 
       And
              rename .htm .html *.htm
 
       will fix the extension of your html files.
aero의 이미지

글쿤요 전 ubuntu를 주로 써서( unbuntu에서는 prename이 원래 파일이고 rename으로 심볼릭링크 걸어놨네요 )
Perl로된 rename 명령은 Perl 창시자인 Larry Wall이 최초로 만든거라 rename명령이 Perl로 된건지 확인하려면

$ grep -i larry `which rename`
#  from Larry Wall's original script eg/rename from the perl source.
# Larry(?)'s RCS header:
Larry Wall

처럼 larry로 해당파일을 grep해서 뭔가가 나오면 맞는거라고 보면 되겠네요.

doodoo의 이미지

doodoo@doodoo:~/git-test$ which rename
/usr/bin/rename
doodoo@doodoo:~/git-test$ file /usr/bin/rename
/usr/bin/rename: symbolic link to `/etc/alternatives/rename'
doodoo@doodoo:~/git-test$ file /etc/alternatives/rename
/etc/alternatives/rename: symbolic link to `/usr/bin/prename'
doodoo@doodoo:~/git-test$ file /usr/bin/prename
/usr/bin/prename: a /usr/bin/perl -w script text executable
doodoo@doodoo:~/git-test$ 

흠..정말로 펄이네요...우분투 10.10 입니다.

lqez의 이미지

저는 linux / mac 을 같이 쓰는데, mac port에는 rename 이 없네요. :(
perl 로 하는 것이 좋겠네요. 감사합니다. :)