使用find和iconv更改文件名

时间:2012-03-29 17:36:55

标签: bash iconv

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

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

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

$ echo ążźćó | iconv -f UTF8 -t ASCII//TRANSLIT
azzco

为什么它在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

我使用xargs得到了相同的结果:

$ find dir/ -type f | xargs -I{} echo {} | iconv -f UTF8 -t ASCII//TRANSLIT
dir/zia

但是:

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

3 个答案:

答案 0 :(得分:6)

以这种方式使用$()的问题是子shell执行 previous 执行find命令,而不是-exec的一部分。你可以做到,但你需要调用bash。类似的东西:

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

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

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

将目录部分拆开,只转换文件名。

答案 1 :(得分:1)

我不太了解iconv,但是

 echo ... | iconv ....

适用于文本字符串,但如果您想使用文件名,当然您需要在iconv命令行的右侧指定文件,即

 ls *.files | xargs -I{}  iconv -f UTF8 -t ASCII//TRANSLIT {}

正确?

至于移动(mv)文件,您必须确保源文件名与目标文件名不同。你不清楚你想要的目标文件名是什么。如果iconv可以就地修改文件并且您不保留原始文件,那么我希望我上面提供的xargs可以解决您的问题。

或者你是说实际的文件名包含要用iconv处理的字符。在iconv处理之前和之后编辑帖子以包含示例文件名可能会有所帮助。像这样的东西?

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

对于iconv未修改的文件名,您必须有一种方法可以将名称与原始文件名分开。所以这将是/bin/rm {}步骤。

或者看到这篇文章How to recursively convert all filenames in folder subtree from UTF-8 to ASCII in Linux

我希望这会有所帮助。

答案 2 :(得分:0)

这也应该有效:

#!/bin/bash
if [ "$1" = "DO" ] ; then
 if [ "$2" != "$3" ]; then
  mv "$2" "$3";
 fi
else
 find dir/ -type f -exec "bash" $0 "DO" {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT )  \;
fi