저는 이름 바꾸기가 처음이고 파스칼 케이스를 사용하는 파일과 폴더가 많으며 이를 소문자로 변환하고 하이픈으로 구분하고 싶습니다. 파일과 폴더에 대해 이 명령을 재귀적으로 실행하고 싶습니다.
예를 들어.
MyFile.txt
~이 되다my-file.txt
MyPhoto.jpg
~이 되다my-photo.jpg
하지만:
ABird.jpg
변함없이 유지되어야 한다USBDisk
변함없이 유지되어야 한다- 의 경우
MyUSBDisk
My-USBDisk 또는 my-USBDisk에 만족합니다. 모든 대문자를 소문자로 변환하는 또 다른 명령이 있으므로 그 전에 가장 중요한 것은 하이픈을 올바른 위치에 배치하는 것입니다.
내 시도가 실패했습니다.
find /path/directory -depth -exec rename 's/\([A-Z]\)/-\L\$1/g' {} \;
그것을 처리하는 방법? 저는 리눅스 민트 21을 사용하고 있습니다.
답변1
rename 's/\([A-Z]\)/-\L\$1/g'
몇 가지가 있습니다. Perl 정규식은 기본 정규식보다 POSIX 확장 정규식에 더 가깝고 \(
/는 \)
리터럴 대괄호와 일치하며 그룹화는 백슬래시 없이 수행됩니다. 또한 오른쪽의 텍스트를 캡처된 그룹으로 \$
만듭니다 . 이 표현식은 첫 글자의 대문자도 캡처하여 처음에 대시를 표시합니다.$
$1
다음과 같은 내용이 됩니다 FooBar
( foo-bar
여기서 이름이 변경된 부분만).
rename 's/([[:lower:]])([[:upper:]])/$1-\L$2/g; s/^([[:upper:]])/\L$1/;' ...
그러나 그것은 또한 USBDisk.img
될 것이다 uSBDisk.img
. 첫 글자 뒤에 또 다른 대문자가 있는 경우 대체를 비활성화하기 위해 음수 예측 검사를 추가할 수 있습니다. 이런 일은 일어나지 않을 것입니다 USBDisk.img
. 그러나 여전히 그럴 것 DiskONE.img
입니다 diskONE.img
.
rename 's/([[:lower:]])([[:upper:]])(?![[:upper:]])/$1-\L$2/g; s/^([[:upper:]])(?![[:upper:]])/\L$1/;' ...
또는 파일 이름에 두 개의 대문자가 연속으로 있으면 전체 프로세스를 건너뜁니다.
rename 'unless (/[[:upper:]]{2}/) { s/([[:lower:]])([[:upper:]])/$1-\L$2/g; s/^([[:upper:]])/\L$1/ }' ...
rename -n -v
변경 사항을 적용하지 않고 먼저 테스트하여 변경 사항을 확인할 수 있습니다 .
물론, 이것은 여전히 Foo-Bar.jpg
결과가 나올 foo-Bar.jpg
것이지만 지금은 연습으로 수정하겠습니다 ...
rename
run을 사용 하려면 find
적절한 -exec
구문을 추가해야 합니다.
find /path/directory -depth -exec rename '...' {} \;
또는 -exec {} +
한 번에 여러 파일 이름을 지정하여 사용하세요.rename
find /path/directory -depth -exec rename '...' {} +
Stéphane이 언급한 것처럼 이름 바꾸기를 파일 이름 부분으로만 제한하고 싶을 수도 있습니다. .(비표준, GNU/BSD) 대신 -d
옵션을 추가 하거나 rename
전환합니다 .-execdir
-exec
답변2
그리고 zsh
:
autoload -Uz zmv
zmv -n '(**/)(*[[:lower:]][[:upper:]]*~*[[:upper:]](#c2)*)' \
'$1${${2//(#b)([[:lower:]])([[:upper:]])/$match[1]-$match[2]}:l}'
<lower><upper>
시퀀스가 하나 이상 있지만 시퀀스가 없는 파일의 이름을 바꾸고 , <upper><upper>
소문자와 대문자 사이에 를 삽입하고 전체 파일을 소문자로 변환합니다.-
( -n
시험 실행을 위해 여기).