使用find和iconv更改文件名

wis*_*ent 4 bash iconv

我试图使用以下脚本更改文件名:

find dir/-type f -exec mv {} $(echo {} | iconv -f UTF8 -t ASCII // TRANSLIT)\;

为什么不起作用?我的意思是当我有一个像'''这样的字符的文件时,它应该将它转换为'a'.

$ echo ????ó | iconv -f UTF8 -t ASCII//TRANSLIT
azzco
Run Code Online (Sandbox Code Playgroud)

为什么它在find -exec中不起作用?

$ find dir/ -type f -exec mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT ) \;
mv: `dir/zi?' and `dir/zi?' are the same file
Run Code Online (Sandbox Code Playgroud)

我使用xargs获得相同的结果:

$ find dir/ -type f | xargs -I{} echo {} | iconv -f UTF8 -t ASCII//TRANSLIT
dir/zia
Run Code Online (Sandbox Code Playgroud)

但:

$ find dir/ -type f | xargs -I{} mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT)
mv: `dir/zi?' and `dir/zi?' are the same file
Run Code Online (Sandbox Code Playgroud)

Fat*_*ror 7

$()以这种方式使用的问题是子shell 执行find命令之前执行,而不是作为其一部分执行-exec.你可以做到,但你需要调用bash.就像是:

find dir/ -type f -exec bash -c 'mv "$1" "$(iconv -f UTF8 -t ASCII//TRANSLIT <<< $1)"' -- {} \;
Run Code Online (Sandbox Code Playgroud)

请记住,这也会转换目录名中的任何特殊字符,这可能会导致mv失败.如果您只想转换文件名,那么您可以:

find dir/ -type f -exec bash -c 'mv "$1" "${1%/*}/$(iconv -f UTF8 -t ASCII//TRANSLIT <<< ${1##*/})"' -- {} \;
Run Code Online (Sandbox Code Playgroud)

将目录部分拆分,只翻译文件名.