Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change file names with find and iconv

Tags:

bash

iconv

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? I mean when I have a file with character like 'ą' it should convert it to 'a'.

$ echo ążźćó | iconv -f UTF8 -t ASCII//TRANSLIT
azzco

why does it not work in 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:

$ 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
like image 394
aleksanderzak Avatar asked Feb 22 '23 00:02

aleksanderzak


1 Answers

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.

like image 75
FatalError Avatar answered Feb 27 '23 00:02

FatalError