将文件递归重命名为 ASCII 标准
Recursively rename files to ASCII Standard
所以我们遇到了一个问题,我们需要抓取数十万张图片并重命名所有图片以符合 ASCII 标准。在网上做了很多研究之后,我们找到了这段方便的代码:
mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')
来源:How to remove invalid characters from filenames
我已经尝试将它合并到一个递归查找命令中,成为 运行 而在我们的主图像目录中:
find . -print0 | xargs -0 mv $(echo | sed -e 's/[^A-Za-z0-9._-]/_/g')
但我似乎无法将其设置为 运行。我得到的最接近的是上面的代码抛出了很多“mv:target filename
Is not a directory”
所以有人可以帮忙吗?
将其放入 shell 脚本中,比如 fixname.sh:
#!/bin/sh
dir=$(dirname "")
name=$(basename "")
newname=$(echo "$name" | sed -e 's/[^A-Za-z0-9._-]/_/g')
if [ "$name" != "$newname" ]; then
if [ ! -e "$newname" ]; then
mv "" "$dir/$newname"
else
echo >&2 "$newname already exist for "
fi
fi
然后像这样使用查找:
find . -type f -exec sh fixname.sh {} \;
我想这样会更好:
find . -type f -exec bash -c 'for f do d=${f%/*} b=${f##*/} nb=${b//[^A-Za-z0-9._-]/_}; [[ $b = "$nb" ]] || echo mv "$f" "$d/$nb"; done' _ {} +
find
将找到所有文件 (-type f
),将它们作为位置参数传递给此 Bash 片段:
for f do
d=${f%/*} b=${f##*/} nb=${b//[^A-Za-z0-9._-]/_}
[[ $b = "$nb" ]] || echo mv "$f" "$d/$nb"
done
我们将文件名拆分为目录名 d
和基本名 b
。我们使用参数扩展将所有不需要的字符替换为下划线,并将该扩展保存到变量 nb
中。我们检查扩展 $b
和 $nb
是否不同(以避免 mv
出现错误),如果它们不同,则执行重命名。
我离开了 echo
这样实际上什么也没有执行,命令只是回显。如果 echo
看起来不错,请将其删除。
请注意,这可能会覆盖文件,例如文件 a&b
和 a_b
。
所以我们遇到了一个问题,我们需要抓取数十万张图片并重命名所有图片以符合 ASCII 标准。在网上做了很多研究之后,我们找到了这段方便的代码:
mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')
来源:How to remove invalid characters from filenames
我已经尝试将它合并到一个递归查找命令中,成为 运行 而在我们的主图像目录中:
find . -print0 | xargs -0 mv $(echo | sed -e 's/[^A-Za-z0-9._-]/_/g')
但我似乎无法将其设置为 运行。我得到的最接近的是上面的代码抛出了很多“mv:target filename
Is not a directory”
所以有人可以帮忙吗?
将其放入 shell 脚本中,比如 fixname.sh:
#!/bin/sh
dir=$(dirname "")
name=$(basename "")
newname=$(echo "$name" | sed -e 's/[^A-Za-z0-9._-]/_/g')
if [ "$name" != "$newname" ]; then
if [ ! -e "$newname" ]; then
mv "" "$dir/$newname"
else
echo >&2 "$newname already exist for "
fi
fi
然后像这样使用查找:
find . -type f -exec sh fixname.sh {} \;
我想这样会更好:
find . -type f -exec bash -c 'for f do d=${f%/*} b=${f##*/} nb=${b//[^A-Za-z0-9._-]/_}; [[ $b = "$nb" ]] || echo mv "$f" "$d/$nb"; done' _ {} +
find
将找到所有文件 (-type f
),将它们作为位置参数传递给此 Bash 片段:
for f do
d=${f%/*} b=${f##*/} nb=${b//[^A-Za-z0-9._-]/_}
[[ $b = "$nb" ]] || echo mv "$f" "$d/$nb"
done
我们将文件名拆分为目录名 d
和基本名 b
。我们使用参数扩展将所有不需要的字符替换为下划线,并将该扩展保存到变量 nb
中。我们检查扩展 $b
和 $nb
是否不同(以避免 mv
出现错误),如果它们不同,则执行重命名。
我离开了 echo
这样实际上什么也没有执行,命令只是回显。如果 echo
看起来不错,请将其删除。
请注意,这可能会覆盖文件,例如文件 a&b
和 a_b
。