파일 과 디렉토리의 이름을 동시에 바꾸려면 일부 문제가 발생합니다 . 파일 이름 만 바꾸면 충분합니다. 그러나 디렉토리의 이름도 바꾸고 싶습니다. 당신은 할 수 단순히 mv Motörhead/Encöding Motorhead/Encoding
때문에 Motorhead
호출의 시간에 존재하지 않습니다.
따라서 모든 파일과 폴더를 우선적으로 탐색 한 다음 현재 파일이나 폴더의 이름 만 바꿉니다. 다음은 find
OS X에서 GNU 및 Bash 4.2.42에서 작동합니다.
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
new="${f//[\\\/\:\*\?\"<>|]/}"
Windows가 처리 할 수없는 항목을 바꾸 려면를 사용하여 정규식을 변경할 수 있습니다.
이 스크립트를로 저장 rename.sh
하고로 실행 가능하게 만드십시오 chmod +x rename.sh
. 그런 다음처럼 호출하십시오 rename.sh /some/path
.
파일 이름 충돌 (“ Notice
”알림) 을 해결하십시오 .
당신이 절대적으로 확신 한다면 는 바로 교체하지의 제거 echo
그냥 무엇을 인쇄하는 대신 실제로 이름 바꾸기 것에 스크립트에서.
안전을 위해 작은 파일 하위 집합에서 먼저 테스트하는 것이 좋습니다.
옵션 설명
여기에 무슨 일이 있는지 설명하려면 :
-depth
디렉토리가 깊이 우선으로 재 확보되도록하여 모든 것을 "롤업"할 수 있습니다. 일반적으로 find
다르게 순회합니다 (단 , 너비 우선은 아님).
-print0
보장하는 find
출력은 우리가 그것을 읽을 수 있도록, 널 (null)로 구분이다 read -d ''
로file
가변. 이렇게하면 공백이있는 파일과 줄 바꿈을 포함하여 모든 종류의 이상한 파일 이름을 처리하는 데 도움이됩니다.
- 우리는 파일의 디렉토리를 얻을 것이다
dirname
. 항상 변수를 올바르게 인용하는 것을 잊지 마십시오. 그렇지 않으면 공백이나 글러브 문자가있는 경로가이 스크립트를 손상시킵니다.
- 로 실제 파일 이름 (또는 디렉토리 이름)을 얻습니다
basename
.
- 그런 다음
$f
Bash의 문자열 교체 기능 을 사용하여 유효하지 않은 문자를 제거합니다 . 유효하지 않음은 소문자 또는 대문자, 숫자, 슬래시 ( \/
), 점 ( \.
), 밑줄 또는 빼기 하이픈이 아닌 것을 의미합니다.
$f
이미 깨끗한 경우 (정리 된 이름이 현재 이름과 동일) 건너 뜁니다.
- 경우
$new
이미 디렉토리에 존재하는 $d
(예를 들어, 당신이라는 이름의 파일이 resume
와 résumé
같은 디렉토리에) 경고를 실행합니다. 일부 시스템에서는 이름을 바꾸고 싶지 않습니다.mv foo foo
문제가 발생 . 그렇지 않으면,
- 마지막으로 원래 파일 (또는 디렉토리)의 이름을 새 이름으로 바꿉니다.
이 때문에 단지 이름 변경, 깊은 계층에 역할을 할 Motörhead/Encöding
에 Motorhead/Encoding
두 단계로 이루어집니다 :
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
이렇게하면 모든 교체가 올바른 순서로 수행됩니다.
예제 파일 및 테스트 실행
기본 폴더의 일부 파일을 다음과 같이 가정합니다 test
.
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
다음은 디버그 모드에서 실행 ( ) echo
앞에 실행 된 결과 mv
, 즉 호출 될 명령 및 충돌 경고입니다.
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
에 대한 메시지의 부재를 주목하라 with-hyphen.txt
, schedule
그리고 test
그 자체.
mv
이미 존재 하는 대상이있는 경우를 처리하기 위해 논리를 추가 할 수 있습니다. (1) 이미 깨끗한mv foo foo
파일이있는 경우 (), (2) 이름이 같은 파일이있는 경우 특수 문자 (예 :에 파일mv Encöding Encoding
이 이미있는 경우 )Encoding
Encöding