递归地将文件重命名为ASCII Standard

时间:2015-10-10 15:53:55

标签: linux bash recursion mv

所以我们遇到一个问题,我们需要爬行数十万个图像并重命名所有图像以符合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不是目录"

所以有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

我想这会更好:

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&ba_b

答案 1 :(得分:2)

将它放在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这样:

find . -type f -exec sh fixname.sh {} \;