使用find和iconv更改文件名

4

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

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个回答

8
使用$()的问题在于子shell在执行-exec命令之前执行,而不是作为其一部分执行find命令。虽然可以这样做,但需要调用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##*/})"' -- {} \;

该功能将目录部分拆分出来,仅转换文件名。


这正是我所缺少的。非常感谢! - aleksanderzak
$(iconv -f UTF8 -t ASCII//TRANSLIT <<< $1) -- 注意这里的$1没有引号,多个空格将被删除!例如,“a{space}{space}b”将变成“a{space}b”。为了避免这种情况,您可以使用带管道的echo -n。 - user2847643

0

我对iconv不是很熟悉,但是

 echo ... | iconv ....

对于文本字符串来说,使用“p”参数是可以的。但如果你想使用文件名进行转换,则需要在 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 {}步骤。
或者,参考这篇文章如何在Linux中递归地将文件夹子树中的所有文件名从UTF-8转换为ASCII
希望这能帮到您。

@wisent:我想我已经完成了对我的帖子的编辑。祝你好运。 - shellter
其实我受到那篇帖子的启发 :) 我只是想为了学习而去做。@FatalError提供了我问题的确切解决方案,但还是谢谢你的贡献。 - aleksanderzak

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接