【问题标题】:Change file names with find and iconv使用 find 和 iconv 更改文件名
【发布时间】:2012-03-29 17:36:55
【问题描述】:

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

查找目录/ -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

【问题讨论】:

    标签: bash iconv


    【解决方案1】:

    以这种方式使用$() 的问题在于子shell 执行先于 执行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##*/})"' -- {} \;
    

    将目录部分分开,只翻译文件名。

    【讨论】:

    • 这正是我所缺少的。非常感谢!
    • $(iconv -f UTF8 -t ASCII//TRANSLIT
    【解决方案2】:

    我不太了解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

    我希望这会有所帮助。

    【讨论】:

    • @wisent :我想我已经完成了对帖子的编辑。祝你好运。
    • 实际上我是受到那篇文章的启发 :) 我只是为了学习目的而这样做。 @FatalError 为我的问题提供了确切的解决方案,但感谢您的贡献。
    【解决方案3】:

    这也应该有效:

    #!/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
    

    【讨论】:

      猜你喜欢
      • 2012-07-01
      • 1970-01-01
      • 2015-09-26
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 2011-03-02
      • 1970-01-01
      相关资源
      最近更新 更多