밑줄 친 공백을 모두 제거하기 위해 다음 쉘 스크립트를 사용해 보았습니다.
find $1 -depth -name "* *" -print0 | \
while read -d $'\0' f; do mv -v "$f" "${f// /_}"; done
디렉토리가 있으면 디렉토리가 /home/user/g h/y h/u j/
수정되고 오류가 발생합니다 .y h
y_h
/home/user/g h/y h/u j
No such file or directory
답변1
이것을 사용하십시오 :
find -name "* *" -print0 | sort -rz | \
while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done
find
이름에 공백이 포함된 파일 및 폴더가 검색됩니다. -print0
특수 파일 이름을 처리하기 위해 널 바이트를 구분 기호로 사용하여 print() 합니다 .
sort -rz
폴더의 가장 깊은 파일이 먼저 이동되고 폴더 자체가 마지막으로 이동되도록 파일 순서를 반대로 바꿉니다 . 따라서 폴더 내의 모든 파일과 폴더 이름이 바뀔 때까지는 폴더 이름이 바뀌지 않습니다.
마지막으로 이 mv
명령은 파일/폴더의 이름을 바꿉니다. 대상 이름에서는 파일의 기본 이름에서 공백만 제거합니다. 그렇지 않으면 더 이상 액세스할 수 없습니다.
답변2
find $1 -depth -name "* *" -type d -execdir rename 's/ /_/g' "{}" \;
답변3
basename
파일 이름(예: 경로의 성)과 다음으로 구분됩니다 dirname
.
find $1 -depth -name "* *" -print0 | \
while read -d $'\0' f ; do
a="$(dirname "$f")"
b="$(basename "$f")"
#optional check if the basename changes -> reduces errors in mv command
#only needed when using -wholename instead of -name in find, so skippable
if [ "${b// /_}" != "$b" ] ; then
mv -v "$a"/"$b" "$a"/"${b// /_}"
fi
done
-depth
상위 디렉토리를 변경하기 전에 먼저 하위 디렉토리를 변경하는 문제가 사양에서 해결되었습니다 find
.