PascalCase를 소문자 하이픈으로 변환

PascalCase를 소문자 하이픈으로 변환

저는 이름 바꾸기가 처음이고 파스칼 케이스를 사용하는 파일과 폴더가 많으며 이를 소문자로 변환하고 하이픈으로 구분하고 싶습니다. 파일과 폴더에 대해 이 명령을 재귀적으로 실행하고 싶습니다.

예를 들어.

  • MyFile.txt~이 되다my-file.txt
  • MyPhoto.jpg~이 되다my-photo.jpg

하지만:

  • ABird.jpg변함없이 유지되어야 한다
  • USBDisk변함없이 유지되어야 한다
  • 의 경우 MyUSBDiskMy-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것이지만 지금은 연습으로 수정하겠습니다 ...


renamerun을 사용 하려면 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시험 실행을 위해 여기).

관련 정보