Change file names with find and iconv

后端 未结 3 1092
天命终不由人
天命终不由人 2021-01-13 12:30

I\'ve tried to change filenames using following script:

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

Why doesn\'t it work

相关标签:
3条回答
  • 2021-01-13 13:06

    This should also work:

    #!/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
    
    0 讨论(0)
  • 2021-01-13 13:11

    I don't know iconv that well, but

     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.

     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 iconv can 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.

    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?

    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.

    OR see this post How to recursively convert all filenames in folder subtree from UTF-8 to ASCII in Linux .

    I hope this helps.

    0 讨论(0)
  • 2021-01-13 13:13

    The problem with using $() in this way is that the subshell executes prior to executing the find command, and not as part of -exec. You can do it, but you'll need to invoke bash. Something like:

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

    Keep in mind this will also translit any special chars in directory names as well, which may cause the mv to fail. If you only want to translit the filename, then you could:

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

    which split the directory portion off and only translits the file name.

    0 讨论(0)
提交回复
热议问题