티스토리 뷰

많은 파일 이름에서 특정 패턴을 찾아서 일괄 변경하기 위한 시도는 오래전부터 있었습니다.

아마도 가장 흔한 방법이 rename 일텐데, rename의 설치 방법에 따라 동작 여부가 약간 달라 문제가 있죠.


일반 pkg에 built-in되어 있는 rename은 파일 명에서 패턴을 찾아 변경하는 옵션이 제공되지 않습니다.

그래서 shell로 도전하게 되었습니다.


일단 결과부터 놓고 풀어나갑니다.

아래는 파일 이름에서 A_A를 찾아 B_B로 변경하는 명령어 입니다.

find . -type f  | xargs -I{} sh -c 'mv -v $0 ${0/A_A/B_B}' {} ;


하나하나 풀어가며 의미를 알아봅니다.


find . -type f

현재 폴더에서 파일 리스트를 가져옵니다.



find . -type f | xargs -I{}

가져온 파일 리스트를 xargs에서 {}로 사용하게 될 겁니다.



find . -type f | xargs -I{} sh -c ...

새로운 sub-shell로, 앞서 구한 것들을 갖고 무언가(mv)를 할 겁니다.



find . -type f  | xargs -I{} sh -c 'mv -v $0 ${0/A_A/B_B}' {};

여기가 핵심인데, 파일 명에서 A_A부분을 찾아 B_B로 변경합니다. (?)

갑자기 뜬금 없죠?


이걸 이해하기 위해서는 $0의 값을 알아야 할 필요가 있습니다.

sh의 -c 옵션일때 $0에 대한 도움말을 잠깐 살펴보면 아래와 같습니다.

-c string If  the  -c  option is present, then commands are read from string.  If there are

                 arguments after the string, they  are  assigned  to  the  positional  parameters,

                 starting with $0.


string이 끝난 이후에 arguments가 있으면 그것을 $0로 받겠다는 의미 입니다.

돌아와서 아래를 보죠.

sh -c 'mv -v $0 ${0/A_A/B_B}' {}

$0 에는 {}의 값이 들어 있는데 앞서 {}에는 find로 찾은 파일 명이 있을겁니다.

그럼 아래처럼 해석이 되겠네요!

mv "원본파일이름" "패턴이 적용된 파일 이름"


간단하면서도 shell script의 구성 하나하나를 모르면 해낼 수 없는 코드 입니다.

누군가 에게 광명이 찾아지기를 바래봅니다.

댓글
  • 프로필사진 국지 좋은 정보 감사합니다.
    질문이 있습니다.
    혹시 파일명이 abc.txt 에서 abc.txt 안의 <def>345 을 찾아서 abc.txt-> 345.txt로 변환하는 스크립트는 어떻게 해야 할까요?
    2016.10.26 01:00 신고
  • 프로필사진 BlogIcon Jaeyeon Baek 댓글을 너무 늦게 봤네요.. 하지만 말씀이 잘 이해되지가 않습니다. 혹 이 글을 보시면 상세한 질문 부탁드리겠습니다. 2016.12.12 13:31 신고
댓글쓰기 폼