리눅스 환경에서 파일 이름을 변경하는 강력한 도구를 살펴보고, `mv` 명령과 작별 인사를 해보세요. 파일 이름 변경은 매우 유연하고 빠르며, 때로는 훨씬 쉽습니다. 여기서는 이 강력한 명령에 대한 사용법을 안내합니다.
`mv` 명령어의 역할
`mv` 명령어 자체에는 아무런 문제가 없습니다. 이 명령어는 모든 리눅스 배포판, macOS 및 기타 유닉스 계열 운영 체제에서 찾을 수 있으며, 파일을 이동하는 데 매우 유용합니다. 물론, 기존 파일을 새 이름으로 옮기는 기능은 파일 이름을 바꾸는 효과를 내므로 사용자가 원하는 결과를 얻을 수 있습니다. 하지만 `mv`는 파일 이름 변경을 위한 전용 도구는 아닙니다.
`mv` 명령어로 단일 파일 이름 변경하기
`mv`를 사용하여 파일 이름을 바꾸려면 `mv`, 공백, 원본 파일 이름, 공백, 그리고 새 파일 이름을 차례로 입력합니다. 그런 다음 Enter 키를 누릅니다.
변경된 사항은 `ls` 명령어를 통해 확인할 수 있습니다.
mv oldfile.txt newfile.txt
ls *.txt
`mv` 명령어로 여러 파일 이름 변경하기
여러 파일의 이름을 한 번에 바꾸려는 경우 상황이 복잡해집니다. `mv` 명령어는 여러 파일을 동시에 변경하는 기능을 제공하지 않기 때문에 Bash 스크립트를 사용해야 합니다. 이 방법은 어느 정도 숙련된 사용자에게는 괜찮지만, `mv`를 사용하여 여러 파일의 이름을 변경하는 과정은 단일 파일의 이름을 변경하는 것보다 훨씬 복잡합니다.
예를 들어, 여러 유형의 파일들이 섞여 있는 디렉토리에서 `.prog` 확장자를 가진 파일들의 확장자를 `.prg`로 변경해야 한다고 가정해 봅시다.
`mv` 명령어를 사용하여 어떻게 이 작업을 처리할 수 있을까요? 먼저 파일들을 확인해 보겠습니다.
ls *.prog -l
다음과 같은 Bash 스크립트 명령어를 사용하여 이 작업을 처리할 수 있습니다.
for f in *.prog; do mv -- "$f" "${f%.prog}.prg"; done
명령어가 잘 실행되었는지 파일들을 다시 한번 확인해 봅시다.
ls *.pr*
확인 결과 모든 `.prog` 파일이 `.prg` 파일로 변경되었음을 알 수 있습니다.
위 명령어의 작동 원리
위의 복잡한 명령어는 실제로 어떤 작업을 수행한 것일까요? 좀 더 자세히 알아보겠습니다.
for f in *.prog; do mv -- "$f" "${f%.prog}.prg"; done
위 명령어의 첫 번째 부분은 디렉토리 내 모든 `.prog` 파일에 대해 반복 작업을 수행하는 루프를 시작합니다.
두 번째 부분은 각 파일에 대해 실행되는 명령어를 정의합니다. `mv` 명령어를 사용하여 각 파일을 새로운 파일 이름으로 이동합니다. 새 파일 이름은 원래 파일 이름에서 `.prog` 부분을 제거하고, 그 자리에 `.prg` 확장자를 추가한 것입니다.
더욱 간단한 방법
물론 더 간단한 방법이 있습니다. 바로 `rename` 명령어입니다.
`rename` 명령어는 표준 리눅스 배포판에 기본적으로 포함되어 있지 않으므로 설치해야 합니다. 또한 리눅스 배포판마다 명령어 이름이 다르지만, 작동 방식은 모두 동일합니다. 사용하는 리눅스 버전에 따라 해당되는 명령어 이름을 사용하면 됩니다.
Ubuntu 및 Debian 계열 배포판에서는 다음과 같이 `rename` 명령어를 설치합니다.
sudo apt-get install rename
Fedora 및 RedHat 계열 배포판에서는 `prename` 명령어를 설치합니다. 여기서 `p`는 Perl을 의미합니다.
sudo dnf install prename
Manjaro Linux에 설치하려면 다음 명령어를 사용합니다. `rename` 명령어는 `perl-rename`이라는 이름으로 제공됩니다.
sudo pacman -Syu perl-rename
`rename` 명령어 사용해 보기
이제 `rename` 명령어를 사용하여 파일 이름을 변경해 보겠습니다. 다시 `.prog` 확장자를 가진 파일들을 준비하겠습니다.
ls *.prog
다음 명령어를 사용하여 파일 이름을 변경한 다음, `ls` 명령어를 통해 결과를 확인해 보겠습니다. Ubuntu 또는 Debian 계열의 Linux를 사용하지 않는 경우, 명령어 이름을 해당 Linux에 맞게 변경해야 합니다.
rename 's/.prog/.prg/' *.prog
ls *.pr*
명령어가 성공적으로 실행되었고, 모든 파일이 `.prg` 확장자로 변경되었으며, 더 이상 디렉토리 내에 `.prog` 파일이 존재하지 않음을 확인할 수 있습니다.
위 명령어의 작동 원리
위의 명령어는 세 부분으로 나누어 설명할 수 있습니다.
첫 번째 부분은 명령어 이름인 `rename`(또는 다른 배포판에서는 `prename`이나 `perl-rename`)입니다.
마지막 부분은 `*.prog`로, 모든 `.prog` 파일에 대해 작업을 수행하도록 지정합니다.
가운데 부분은 각 파일 이름에 대해 수행할 작업을 정의합니다. `s`는 대체를 의미합니다. 첫 번째 용어(`.prog`)는 `rename` 명령어가 각 파일 이름에서 검색할 문자열이고, 두 번째 용어(`.prg`)는 대체될 문자열입니다.
명령어의 중간 부분, 즉 핵심 표현식은 Perl의 정규 표현식을 사용하며, 이것이 `rename` 명령어에 유연성을 부여합니다.
파일 이름의 다른 부분 변경
지금까지 파일 이름 확장자를 변경했지만, 파일 이름의 다른 부분도 변경해 보겠습니다.
예를 들어, C 소스 코드 파일이 많이 들어있는 디렉토리가 있고, 모든 파일 이름이 `slang_` 접두사로 시작한다고 가정해 봅시다. 이를 `ls` 명령어를 통해 확인할 수 있습니다.
ls sl*.c
이제 `slang_`를 `sl_`로 변경해 보겠습니다. 명령어 형식은 이미 익숙합니다. 검색어, 대체 용어, 그리고 파일 형식만 변경하면 됩니다.
rename 's/slang_/sl_/' *.c
이 명령어는 `.c` 파일을 찾고, 각 파일 이름에서 `slang_`를 검색합니다. `slang_`가 발견될 때마다 `sl_`로 대체됩니다.
위에서 사용한 `ls` 명령어를 다시 사용하면 결과를 확인할 수 있습니다.
ls sl*.c
파일 이름의 일부 삭제
검색어를 지정하고, 대체 용어를 지정하지 않음으로써 파일 이름의 일부를 삭제할 수도 있습니다.
ls *.c
rename 's/sl_//' *.c
ls *.c
`ls` 명령어의 결과에서, 모든 `.c` 파일에 `sl_` 접두사가 추가된 것을 볼 수 있습니다. 이제 이 접두사를 삭제해 보겠습니다.
`rename` 명령어는 이전과 동일한 형식을 따릅니다. `.c` 파일을 찾고, 검색어는 `sl_`이지만 대체 용어는 없습니다. 두 개의 슬래시 사이에 아무것도 없다는 것은 빈 문자열을 의미합니다.
`rename` 명령어는 각 `.c` 파일을 차례대로 처리합니다. 파일 이름에서 `sl_`를 검색하고, 발견되면 아무것도 대체하지 않습니다. 즉, 검색어가 삭제되는 효과를 냅니다.
`ls` 명령어를 다시 사용하면 모든 `.c` 파일에서 `sl_` 접두사가 제거되었음을 확인할 수 있습니다.
파일 이름의 특정 부분에 대한 변경 제한
`ls` 명령어를 사용하여 파일 이름에 `param` 문자열이 있는 파일을 찾아보겠습니다. 그 다음 `rename` 명령어를 사용하여 `param` 문자열을 `parameter` 문자열로 바꿉니다. 변경 사항을 확인하기 위해 `ls` 명령어를 다시 사용합니다.
ls *param*
rename 's/param/parameter/' *.c
ls *param*
파일 이름에 `param`을 포함하는 4개의 파일이 검색되었습니다. `param.c`, `param_one.c`, 그리고 `param_two.c`는 이름 시작 부분에 `param`을 포함하고 있습니다. 반면 `third_param.c`는 이름 끝부분에 `param`을 포함하고 있습니다.
`rename` 명령어는 파일 이름의 모든 위치에서 `param`을 찾아 `parameter`로 바꿉니다.
`ls` 명령어를 다시 사용하면, 이 결과가 정확함을 확인할 수 있습니다. `param`이 파일 이름의 시작 부분에 있든 끝 부분에 있든 상관없이, 모두 `parameter`로 대체되었습니다.
Perl의 메타 문자를 사용하여 중간 표현식의 동작을 향상시킬 수 있습니다. 메타 문자는 문자의 위치나 순서를 나타내는 기호입니다. 예를 들어, `^`는 “문자열의 시작”을 의미하고, `$`는 “문자열의 끝”을 의미하며, `.`는 개행 문자를 제외한 모든 단일 문자를 의미합니다.
파일 이름의 시작 부분에만 검색을 제한하기 위해, 문자열 시작 메타 문자(^)를 사용해 보겠습니다.
ls *param*.c
rename 's/^parameter/value/' *.c
ls *param*.c
ls value*.c
이전에 이름을 변경한 파일들이 나열되었으며, `parameter` 문자열이 세 파일 이름의 시작 부분에 위치하고 있고, 한 파일 이름의 끝에 있는 것을 확인할 수 있습니다.
`rename` 명령어는 검색어 `parameter` 앞에 줄 시작 메타 문자(^)를 사용합니다. 이는 검색어가 파일 이름의 시작 부분에 있는 경우에만 검색된 것으로 간주하도록 `rename` 명령어에 지시합니다. 검색 문자열 `parameter`가 파일 이름의 다른 위치에 있는 경우에는 무시됩니다.
`ls` 명령어를 통해 확인해 보면, 파일 이름 끝에 `parameter`가 있는 파일 이름은 수정되지 않았지만, 이름 시작 부분에 `parameter`가 있는 세 개의 파일 이름에서는 검색 문자열이 `value`라는 용어로 대체되었음을 알 수 있습니다.
`rename` 명령의 강력함은 Perl의 강력함에서 나옵니다. 사용자는 Perl의 모든 기능을 활용할 수 있습니다.
그룹으로 검색하기
`rename` 명령어에는 아직 더 많은 기능이 있습니다. 파일 이름에 유사한 문자열이 있는 경우를 생각해 보겠습니다. 이 문자열들이 정확히 일치하지 않으므로 간단한 검색 및 대체는 사용할 수 없습니다.
이 예에서, `ls` 명령어를 사용하여 `str`로 시작하는 파일이 있는지 확인합니다. `string.c`와 `strangle.c`의 두 개의 파일이 있습니다. 그룹화 기술을 사용하여 이 두 문자열의 이름을 한 번에 변경할 수 있습니다.
이 `rename` 명령어의 중심 표현식은 파일 이름 내에서 문자 시퀀스 `stri` 또는 `stra`를 찾고, 이 시퀀스 뒤에 `ng`가 따라오는 문자열을 검색합니다. 즉, 이 검색어는 `string`과 `strang`을 찾을 것입니다. 대체 용어는 `bang`입니다.
ls str*.c
rename 's/(stri|stra)ng/bang/' *.c
ls ban*.c
`ls` 명령어를 다시 사용하면 `string.c`가 `bang.c`가 되었고, `strangle.c`가 `bangle.c`가 되었음을 확인할 수 있습니다.
`rename` 명령어와 함께 번역 기능 사용
`rename` 명령어는 파일 이름에 대한 “번역” 작업을 수행할 수도 있습니다. 간단한 번역 예는 파일 이름 집합을 모두 대문자로 변경하는 것입니다.
아래 `rename` 명령어에서, 중간 표현식을 시작하기 위해 `s/`가 아닌 `y/`를 사용하고 있다는 것을 알아두십시오. 이것은 대체 작업이 아닌 번역 작업을 수행한다는 것을 `rename` 명령어에 알립니다.
`a-z`는 a부터 z까지의 모든 소문자를 나타내는 Perl 표현식입니다. 마찬가지로, `A-Z`는 A부터 Z까지의 모든 대문자를 나타냅니다.
이 명령어의 핵심 표현식은 다음과 같이 해석할 수 있습니다. “파일 이름에서 a부터 z까지 소문자를 발견하면, A부터 Z까지의 대문자 시퀀스에서 해당 문자로 바꾸십시오.”
모든 `.prg` 파일의 이름을 대문자로 바꾸려면 다음 명령어를 사용합니다.
rename 'y/a-z/A-Z/' *.prg
ls *.PRG
`ls` 명령어는 모든 `.prg` 파일 이름이 이제 대문자로 변경되었음을 보여줍니다. 사실, 엄밀히 말하면 더 이상 `.prg` 파일이 아닙니다. `.PRG` 파일입니다. 리눅스는 대소문자를 구분합니다.
중간 표현식에서 `a-z`와 `A-Z` 항의 위치를 뒤집으면, 마지막 명령어를 역전시킬 수 있습니다.
rename 'y/A-Z/a-z/' *.PRG
ls *.prg
5분 안에 Perl을 배울 수는 없습니다.
Perl을 이해하는 데 많은 시간을 할애했지만, `rename` 명령어의 시간 절약 기능을 활용하기 시작하려면 많은 Perl 지식이 필요하지 않습니다. 단지 성능, 단순성, 그리고 시간 면에서 엄청난 이점을 얻을 수 있습니다.