스크립트는 디렉터리/하위 디렉터리의 각 파일을 반복적으로 살펴보고(심볼릭 링크 건너뛰기) 파일 이름을 다음과 같이 대체해야 합니다.
- 여러 개의 연속된 공백은 하나의 공백만 해당
- 여러 개의 연속 _ 하나만 포함 _
- 하나 이상의 밑줄과 하나 이상의 공백(밑줄은 하나만 포함)
- 밑줄 다음에 - 밑줄만
- - 뒤에 밑줄이 오고 밑줄만 나타납니다.
- 여러 개의 연속된 "."에는 점이 1개만 있습니다.
- 파일 접미사를 모두 소문자로 만듭니다(예: .PdF에서 .pdf로) 이는 단지 예일 뿐입니다.
- @, $ 또는 !와 같은 문자를 제거하세요.
답변1
사용 find
및 Perl rename
:
참고: Perl은 다양한 Linux 배포판에서 , , 또는 .perl rename
로도 알려져 있습니다 . 기능과 명령줄 옵션이 완전히 다르고 호환되지 않는 유틸리티와 혼동하지 마십시오 .file-rename
perl-rename
prename
rename
util-linux
find . -type f -print0 |
rename -n -0 '
s/[\@\$!]//g; # remove all @, $, and ! characters.
# remove leading and trailing whitespace (if any) from filenames
s/^\s+|\s*\z//sg;
# change all runs of any whitespace to just one space
s/\s+/ /sg;
s/[- ]*([._])[- ]*/$1/g; # remove space(s) and - around _ and .
s/\.\.+/./g; # reduce multiple periods to just one
s/__+/_/g; # reduce multiple _ to just one
s/_*\._*/./g; # change _. and ._ to just .
s=(\.[^./]*\z)=lc($1)=e; # lowercase filename suffixes
'
세 번째 대체 유형은 연속된 하나 이상의 공백 문자(실제 공백 문자, 탭, 줄 바꿈, 폼 피드 등 포함)를 단일 공백 문자로 대체합니다. IMO는 요청한 것 이상이지만 파일 이름에서 공백 문자만 바꾸는 것보다 다양한 유형의 공백 문자를 모두 바꾸는 것이 더 유용할 수 있습니다. 원하는 내용이 아닌 경우 (공백 2개와 공백 1개) \s+
로 변경하세요 +
.+
네 번째 대체( ) s/[- ]*([_.])[- ]*/$1/g;
는 또는 앞에 공백이나 _
대시가 필요하지 않다고 가정합니다 .
. 이는 귀하가 요청한 것보다 많지만 실제로 필요한 것보다 많은 경우 쉽게 변경할 수 있습니다.
관련하여 두 번째 대체는 _.
및 로만 대체됩니다. 이렇게 하면 와 같은 파일 이름을 얻을 수 없습니다. 이와 같은 파일 이름을 원하면 이 줄을 제거하세요.._
.
foo_.bar_._pdf
마지막 대체의 정규식 수정자는 e
대체가 Perl 코드(이 경우 lc()
입력을 소문자로 만드는 함수)로 평가되도록 합니다.
참고: -n
옵션의 이름을 변경하여 수행할 작업만 보여주는 시험 실행으로 만듭니다. 실제로 파일 이름을 바꾸려면 파일을 삭제 -n
하거나 변경하여 -v
자세한 출력을 얻으세요.
또한 원하는 경우 여러 줄 이름 바꾸기 스크립트를 하나의 길고 읽을 수 없는 줄로 압축할 수 있습니다(주석을 제거한 경우). #
그러나 추가 줄 바꿈 및 들여쓰기를 사용하면 명령줄에서 읽기 및 편집이 더 쉬워집니다. 그리고 스크립트에서.
마지막으로 이것은 당신이 말할 때"디렉토리/하위 디렉터리의 모든 파일 찾아보기(기호 링크 건너뛰기)"또한 이름 변경에서 디렉터리, 장치 노드, 명명된 파이프, 소켓 등을 제외하려고 합니다. 즉, 일반 파일만 이름이 변경됩니다.
일치하는 디렉터리의 이름도 바꾸려면 -type f
로 find
변경 해야 합니다 \( -type f -o -type d \)
.
물론 원하는 find 조건자를 사용하여 검색을 구체화할 수 있습니다.
답변2
라는 유틸리티가 있습니다.디톡스이것은 많은 문제를 해결할 수 있습니다. 웹페이지에서:
- 대문자 ASCII Latin-1(ISO 8859-1) 문자(즉, 왼쪽 및 오른쪽 큰따옴표)를 제거하거나 바꿉니다. 가능할 때마다 대체 문자가 사용됩니다(예: 위의 악센트가 있는 "A"가 "A"로 대체됩니다).
- UTF-8로 인코딩된 유니코드 문자를 제거하거나 교체합니다. 이는 유니코드의 범위가 훨씬 더 넓다는 점을 제외하면 ISO 8859-1 번역과 동일한 방식으로 작동합니다.
- 공백과 (,) 및 @와 같이 까다로울 수 있는 기타 문자를 제거하거나 교체합니다. 파일 이름 시작 부분의 "-"를 제거하십시오.
- CGI 이스케이프된 ASCII 문자를 제거하거나 바꾸십시오. 즉, %20은 " "(그리고 "_")가 됩니다.
- 초과된 "_" 및 "-"를 자릅니다.
- 디렉터리 재귀, 시험 실행, 세부 목록.
- 안전을 염두에 두고 설계되었습니다. 이미 존재하는 파일을 덮어쓰지 않으며 특수 파일은 일반적으로 건드리지 않습니다(그러나 요청할 수 있음).
답변3
그리고 zsh
:
autoload -Uz zmv
zmv -n '(**/)(*)' '$1${${${${${2//[@\$!]}//[ _]##/_}//.##/.}//[-_]#_[-_]#/_}/%(#m).[^.]#/$MATCH:l}'
( 만족스러우면 -n
시험 실행을 위해 제거하십시오 ).
이는 일부 ${param//pattern/replacemenet}
연산자와 중첩됩니다.
${2//[@\$!]}
:( 파일의 기본 이름)@
$
!
에서 모든 s를 제거합니다.$2
공간이 생길 수 있으므로 먼저 이 작업을 수행_
하거나-
후속 단계에서 함께 압축해야 할 수도 있습니다.${...//[ _]##/_}
: 위 결과에서##
하나 이상의 공백( ) 또는 밑줄을 다음으로 대체합니다._
${...//.##/.}
: 위 결과에서##
하나 이상의 ( ) 순서를.
다음으로 대체하십시오..
${...//[-_]#_[-_]#/_}
: 위 결과를 기준으로 0개 이상(#
)_
또는-
양면이 있는 항목을 삭제합니다._
_
${.../%(#m).[^.]#/$MATCH:l}
: 수정자를 사용하여 소문자로 변환된 동일한 내용으로 끝 부분의 a( ).
와 일련의 s가 아닌 문자를 대체합니다(대체 시 일치 항목을 사용할 수 있도록 함)..
%
(#m)
$MATCH
:l
zmv
디렉터리 깊이가 먼저 처리되고(해당 지점 이전에 나옴) 이름 바꾸기를 시작하기 전에 데이터가 손실되지 않았는지 확인하기 위한 일부 온전성 검사를 통해 교체가 수행됩니다.
예를 들어 다음과 같이 하십시오:
mv -- 'A _ - _ .. - b -c-d ..PDF' A_._b_c-d_.pdf