macOS에서 find 및 mv를 사용하여 디렉터리 이름 바꾸기

macOS에서 find 및 mv를 사용하여 디렉터리 이름 바꾸기

디렉터리와 파일의 이름을 바꾸는 명령으로 어려움을 겪고 있습니다.

  • 운영 체제: MACOS 11.4
  • 목표: 공백을 밑줄로 바꿔 디렉터리 및 파일 이름 바꾸기_
  • 시도해 볼 명령:
    find . -maxdepth 1 -iname "* *" -exec sh -c 'fichier="{}"; mv -- $fichier ${fichier// /_}' \;
    

find나는 한 번에 1레벨 깊이의 디렉토리 트리를 탐색할 수 있기를 원하기 때문에 이것을 사용합니다 .

이 명령의 결과는 다음과 같습니다.

usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory

그래서 mv나는 echo명령을 확인하는 데 사용하지 않습니다

find . -maxdepth 1 -iname "* *" -exec sh -c 'fichier="{}"; echo $fichier ${fichier// /_}' \;

이것은 예상대로 작동하는 것 같습니다.

./Job offers etc ./Job_offers_etc
./School results ./School_results
./Famille et Souvenirs ./Famille_et_Souvenirs
./KID education ./KID_education
./Template Open Office-MS Office ./Template_Open_Office-MS_Office
./Mode Emplois ./Mode_Emplois
./cartres de voeux ./cartres_de_voeux

내가 그것을 사용할 때 무엇을 잘못했습니까 mv?

답변1

현재 겪고 있는 상황은 이 작업을 권장하는 이유 중 하나입니다.(거의) 항상 쉘 변수를 인용하십시오..

귀하의 경우, 쉘 변수에 fichier공백이 포함된 파일 이름을 지정했으므로 변수를 "있는 그대로" 사용하면 쉘은 토큰화를 수행합니다. 즉, 인수인 디렉토리는 다음과 같습니다 $fichier. 세 개의 파일을 대상 디렉터리 로 이동합니다 (1) .Job offers etcmvJoboffersetcJob_offers_etc

이 문제를 방지하려면 에 표시된 대로 변수 참조 주위에 큰따옴표를 넣으십시오 "$fichier".


(1) 이것은 실제로 위험할 수 있습니다. 대상 디렉토리가 존재하지 않는 경우 이 명령은 세 개의 파일 이름을 동일한 이름으로 변경하여 처음 두 파일을 세 번째 파일로 덮어쓸 수 있습니다.

답변2

Perl 이름 바꾸기 유틸리티가 있는 경우파일::이름 바꾸기, 이미 설치되어 있으므로 쉽습니다. 아직 안 했다면, 당신은~해야 한다설치하세요. 어려운 일괄 이름 변경 작업이 매우 쉬워집니다.

당신이 가지고 있다면스스로 만든설치되어 있으면 다음 명령을 사용하여 설치할 수 있습니다 brew install rename(참조:추출 시 이름 바꾸기) 그렇지 않으면 설치할 수 있습니다 cpan. 마찬가지로 Mac에 Homebrew가 설치되어 있지 않은 경우~해야 한다, 수천 개의 패키지에 대한 액세스를 제공합니다.

그런 다음 현재 디렉터리의 모든 파일 이름 + 디렉터리 이름의 공백을 밑줄로 바꿀 수 있습니다.

rename -n 's/ /_/g' *

-n옵션을 사용하면 시험적으로 실행될 수 있으며 실제로 파일 이름이 바뀌지는 않고 이름이 바뀔 내용만 표시됩니다. 원하는 대로 작동한다고 확신하면 옵션을 제거 하거나 자세한 출력으로 -n바꾸세요 .-v

Perl rename은 이름 바꾸기 스크립트가 실제로 파일 이름을 변경하는 경우에만 파일 이름 바꾸기를 시도하고 위의 스크립트는 공백 없이 파일 이름을 변경하지 않기 때문에 공백이 포함되지 않은 파일을 제외할 필요가 거의 또는 전혀 없습니다.

또한 강제로 실행하지 않는 한 기존 파일 이름으로 파일 이름을 바꾸는 것을 거부합니다 -f.

원하는 경우 find와 함께 사용할 수 있으며 NUL로 구분된 입력을 이해합니다(따라서 those줄 바꿈이 포함된 파일 이름도 포함하여 모든 파일 이름을 처리할 수 있습니다). 예를 들어

find . -maxdepth 1 -iname "* *" -print0 | rename -0 -n 's/ /_/g'

답변3

find및 의 조합 sh -c과 변수 참조의 필요성 때문에 루프를 사용하는 것이 더 쉬울 수 있습니다 for.

for file in *\ *
do
  newfile=$(echo "$file" | tr ' ' _)
  mv -i "$file" "$newfile"
done

관련 정보