我尝试使用以下 shell 脚本删除所有带下划线的空格:
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
使用空字节作为分隔符来打印 ( ),以处理特殊文件名。
反转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
。