bash 使用 find 和 iconv 更改文件名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9930484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change file names with find and iconv
提问by wisent
I've tried to change filenames using following script:
我尝试使用以下脚本更改文件名:
find dir/ -type f -exec mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT ) \;
find dir/ -type f -exec mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT ) \;
Why doesn't it work? I mean when I have a file with character like '?' it should convert it to 'a'.
为什么不起作用?我的意思是当我有一个像 '?' 这样的字符的文件时 它应该将其转换为'a'。
$ echo ????ó | iconv -f UTF8 -t ASCII//TRANSLIT
azzco
why does it not work in find -exec?
为什么它在 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
I get the same results using xargs:
我使用 xargs 得到相同的结果:
$ find dir/ -type f | xargs -I{} echo {} | iconv -f UTF8 -t ASCII//TRANSLIT
dir/zia
but:
但:
$ find dir/ -type f | xargs -I{} mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT)
mv: `dir/zi?' and `dir/zi?' are the same file
回答by FatalError
The problem with using $()in this way is that the subshell executes priorto executing the findcommand, and not as part of -exec. You can do it, but you'll need to invoke bash. Something like:
$()以这种方式使用的问题是子shell在执行find命令之前执行,而不是作为-exec. 你可以这样做,但你需要调用 bash。就像是:
find dir/ -type f -exec bash -c 'mv "" "$(iconv -f UTF8 -t ASCII//TRANSLIT <<< )"' -- {} \;
Keep in mind this will also translit any special chars in directory names as well, which may cause the mvto fail. If you only want to translit the filename, then you could:
请记住,这也将转译目录名称中的任何特殊字符,这可能会导致mv失败。如果您只想转译文件名,那么您可以:
find dir/ -type f -exec bash -c 'mv "" "${1%/*}/$(iconv -f UTF8 -t ASCII//TRANSLIT <<< ${1##*/})"' -- {} \;
which split the directory portion off and only translits the file name.
它将目录部分分开并只转换文件名。
回答by shellter
I don't know iconv that well, but
我不太了解 iconv,但是
echo ... | iconv ....
is fine for text strings, but if you want you use a filename, certainly you need to specify the file on the right-hand-side of the iconv command line, i.e.
对于文本字符串很好,但是如果你想使用文件名,当然你需要在 iconv 命令行的右侧指定文件,即
ls *.files | xargs -I{} iconv -f UTF8 -t ASCII//TRANSLIT {}
right?
对?
As for moving (mv) a file, you have make sure that the source filename is different from the target filename. It's not clear from you post what you want the target filename to be. If iconvcan modify files in-place AND you don't care to keep the original, then I would expect the xargs I provide above should solve your problem.
至于移动 ( mv) 文件,您必须确保源文件名与目标文件名不同。您发布的目标文件名并不清楚。如果iconv可以就地修改文件并且您不关心保留原始文件,那么我希望我上面提供的 xargs 应该可以解决您的问题。
OR are you saying that the actual filenames contains characters that you want to process with iconv. It might help to edit your post to include sample filenames, before and after iconv processing. Something like this?
或者你是说实际的文件名包含你想用iconv. 在 iconv 处理之前和之后,编辑您的帖子以包含示例文件名可能会有所帮助。像这样的东西?
find dir/ -type f -exec mv {} $(echo {}.fix | iconv -f UTF8 -t ASCII//TRANSLIT ) \;
For filenames that don't get modified by iconv, you have to have a way to make the name separate from the original filename. So this would be followed by an /bin/rm {}step.
对于没有被 修改的文件名iconv,您必须有办法将名称与原始文件名分开。所以这将是一个/bin/rm {}步骤。
OR see this post How to recursively convert all filenames in folder subtree from UTF-8 to ASCII in Linux.
或查看这篇文章How to recursively convert all filenames in folder subtree from UTF-8 to ASCII in Linux。
I hope this helps.
我希望这有帮助。
回答by pizza
This should also work:
这也应该有效:
#!/bin/bash
if [ "" = "DO" ] ; then
if [ "" != "" ]; then
mv "" "";
fi
else
find dir/ -type f -exec "bash" ##代码## "DO" {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT ) \;
fi

