所以我们有一个问题,我们需要抓取成千上万的图像,并重命名所有的图像符合ASCII标准。 在网上做了大量的研究之后,我们发现了这个方便的一段代码:
mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')
源自: 如何从文件名中删除无效字符
我已经尝试将它合并到recursion查找命令中,以便在我们的主映像目录中运行:
find . -print0 | xargs -0 mv $(echo | sed -e 's/[^A-Za-z0-9._-]/_/g')
但我似乎无法让它运行。 最近我得到了,是上面的代码扔了很多“MV:目标filename
是不是一个目录”
那么任何人都可以帮忙吗?
我想这会更好:
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
我们将文件名拆分为dirname d
和basename b
。 我们使用参数扩展来将所有不需要的字符替换为下划线,并将该扩展保存到变量nb
。 我们检查扩展$b
和$nb
是否不同(以避免mv
错误),如果它们不同,则执行重命名。
我离开echo
以便没有任何实际执行,命令只是回应。 如果看起来不错,请删除echo
。
请注意,这可以覆盖文件,例如文件a&b
和a_b
。
把这个放在shell脚本中,比如fixname.sh:
#!/bin/sh dir=$(dirname "$1") name=$(basename "$1") newname=$(echo "$name" | sed -e 's/[^A-Za-z0-9._-]/_/g') if [ "$name" != "$newname" ]; then if [ ! -e "$newname" ]; then mv "$1" "$dir/$newname" else echo >&2 "$newname already exist for $1" fi fi
然后使用找到像这样:
find . -type f -exec sh fixname.sh {} \;