我尝试使用以下脚本更改文件名:
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
答案 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