如果要同时重命名文件和目录,将会遇到一些问题。重命名一个文件很容易。但是您要确保目录也被重命名。您不能简单地说,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)。