잘못된 파일 이름을 수정하는 쉘 스크립트?

잘못된 파일 이름을 수정하는 쉘 스크립트?

저는 소규모 회사의 IT입니다. 그리고 내 무서운 경고에도 불구하고 모든 사람은 앞뒤 공백, 잘못된 문자( \ ; / + . < > -등 포함!) 를 포함하여 끔찍한 이름을 가진 파일을 서버에 넣습니다.

Mac에서 AFP를 통해 (FreeBSD/FreeNAS) 서버에 액세스하여 이를 수행하므로 시스템의 어떤 부분도 불평하지 않습니다.

전체 디렉토리 트리를 탐색하여 잘못된 파일 이름을 수정하는 데 사용할 수 있는 스크립트가 있습니까?

기본적으로 모든 공백과 잘못된 ASCII를 _...로 바꾸고 파일이 이미 존재하는 경우 _2끝에 a 또는 무언가를 두드리십시오.

시스템을 구축할 수 있는 방법은 없는 것 같습니다.억지로 시키다좋은 파일 명명 규칙이 있나요?

감사해요!

답변1

나는 bash를 사용하여 찾을 것입니다. 더 간단한 옵션이 있다고 확신하지만 제가 생각해낸 것은 다음과 같습니다.

  1. 이는 "/"가 포함된 파일 이름을 처리할 수 있지만(find는 경고를 표시하고 무시합니다)현재 디렉터리의 파일에서만 작동합니다.(하위 디렉터리 없음) 파일 이름의 "/"와 경로의 일부인 "/"를 구별하기 위해 bash 또는 find를 말하는 방법을 알 수 없었습니다.

    for i in $(find . -maxdepth 1 -type f  -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" | sed 's/\.\///'); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}; done
    
  2. 이 하나할 수 없다"/"가 포함된 파일 이름을 처리하지만 현재 디렉터리의 모든 파일에서 작동합니다.및 해당 하위 디렉터리:

    for i in $(find . -type f  -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%]/_}; done
    

반드시실행하기 전에 테스트해 보세요.. 제가 실행한 몇 가지 테스트에서는 잘 작동했지만 완벽하지는 않았습니다. 또한 나는 Linux 시스템을 사용하고 있다는 점을 명심하십시오. find 및 bash의 특정 구현은 사용자마다 다를 수 있습니다.


편집: mv $i명령을 `mv -i $i'로 변경하면 mv가 기존 파일을 덮어쓰기 전에 메시지를 표시하게 됩니다.

EDIT2: 공백이 있는 파일 이름을 처리하려면 bash IFS(입력 필드 구분 기호) 변수를 다음과 같이 변경할 수 있습니다.여기):

SAVEIFS=$IFS; IFS=$(echo -en "\n\b"); for i in $(find . -type f  -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%\ ]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%\ ]/_}; done; IFS=$SAVEIFS

또한 공백을 밑줄과 일치/대체하도록 정규식을 수정했습니다. SAVEIFS 비트는 IFS 변수를 원래 구성으로 반환합니다.


설명:

for i in $(command); do something $i; done

이것은 일반적인 bash 루프입니다. 명령의 출력을 통해 $i 변수를 명령에서 반환된 각 값에 순차적으로 설정하고 이에 대해 작업을 수행합니다.


find . -maxdepth 1 -type f  -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" '

이름에 다음 문자 중 하나가 포함된 현재 디렉터리의 모든 파일을 찾습니다 :;><@$#&()\/%. 더 추가하려면 "\"(예: "\¿")로 이스케이프 처리하고 대괄호([ ]) 안의 목록에 추가하세요. 아마도 이러한 문자를 모두 이스케이프해야 하는 것은 아니지만 어떤 환경에 특수 변수가 있는지 기억할 수 없으므로 만일을 대비해 모든 문자를 이스케이프해야 합니다.

sed 's/\.\///

find의 출력에서 ​​현재 디렉터리를 제거하고 "./foo" 대신 "foo"를 인쇄합니다.

mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}

이 작은 scipt가 반복될 때마다 $i는 이름이 잘못된 파일의 이름이 됩니다. 이 명령은 원하지 않는 모든 문자를 "_"로 변경하여 해당 파일을 이동(이름 변경)합니다. 자세한 내용은 bash 대체를 찾아보세요.


관련 정보