파일 이름에서 모든 특수 문자를 재귀적으로 제거합니다.

파일 이름에서 모든 특수 문자를 재귀적으로 제거합니다.

내 디렉터리 및 하위 디렉터리의 여러 파일에는 Microsoft 파일 공유 및 SharePoint에서 지원되지 않는 특수 문자가 포함되어 있습니다. 문자 유형은 물결표에서 앰퍼샌드, 누가 알 수 있는지에 이르기까지 다양합니다. 나는 다음 명령을 사용했습니다.

find . -type f -print | while read file
do
  file_clean=$( echo ${file} | tr " \~()&'" "_____" )
  mv $file $file_clean
done

누군가가 globstar 사용을 제안하는 것을 보았습니다. 그러나 모든 특수 문자를 제거하고 AZ, az, 0-9만 재귀적으로 남기는 상대적으로 간단한 명령을 여전히 찾을 수 없습니다(재귀가 가장 어려운 부분인 것 같습니다).

답변1

가장 간단한 방법은다루기 힘든. Zsh는 기본 OS X 설치의 일부이지만 대부분의 Linux 배포판의 패키지 관리자와 *BSD의 포트를 통해 설치해야 합니다. Zsh는 제공합니다zmv기능을 사용하면 많은 파일 이름 바꾸기 작업이 쉬워집니다. 먼저 실행하십시오(또는 .zshrc대화식 사용을 위해 사용자의 컴퓨터에 넣으십시오 ).

autoload zmv

그런 다음 사용할 수 있습니다

zmv '(**/)(*)' '$1${2//[^A-Za-z0-9]/_}'

또는 이에 상응하는

zmv '**/*' '$f:h${${f:t}//[^A-Za-z0-9]/_}'

첫 번째 zmv명령은 일치하는 모든 파일 (즉, **/*현재 디렉터리와 하위 디렉터리의 모든 파일을 재귀적으로)의 이름을 동일한 디렉터리 ( a ) $1에 있는 [^A-Za-z0-9]파일 로 바꾸고 파일의 기본 이름은 에 할당합니다 . 두 번째 명령은 동일한 작업을 수행하지만 전체 원래 이름을 인용하고_(**/)(*)/$1$2$f수정자 :h:t이름의 디렉터리와 기본 부분을 추출합니다 .


다양한 특수 문자를 문자 그대로 처리하는 대신 쉘 처리를 통해 실행하기 때문에 스크립트가 다양한 방식으로 중단됩니다. 이유를 이해하려면 다음을 읽어보세요.공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?

답변2

모든 파일 이름을 얻으려면 빈 제거 문자열에 의존해야 합니다:

find /your/path/ -print0 | while read -r -d $'\0' filename; do
    dn="`dirname "$filename"`"
    bn="`basename "$filename"`"
    bn_clean="`echo "$bn" | tr " \~()&'" "_______"`"
    file_clean="$dn/$bn_clean"
    if [ "$filename" != "$file_clean" ] ; then
        mv -fv "$filename" "$file_clean"
    fi
done

답변3

다음 사항에 주의하세요.

perl -pi -e 's/\W//g' $(find . -type f)

백업에는 다음 방법을 사용할 수 있습니다.

perl -pi.bak -e 's/\W//g' $(find . -type f)

관련 정보