I have been trying to recursively rename files AND folders with iconv without success, the files are correctly renamed but folders dont.
What I use for files is (works perfect):
find . -name * -depth \ -exec bash -c 'mv "$1" "${1%/*}/$(iconv -f UTF8 -t ASCII//TRANSLIT <<< ${1##*/})"' -- {} \;
What I tried for files AND folders (fail: Only rename folders):
find . -exec bash -c 'mv "$1" "$(iconv -f UTF8 -t ASCII//TRANSLIT <<< $1)"' -- {} \;
ORIGINAL problem: I just want to bulk rename lots of files to make them "web friendly", thinks like removing spaces, weird characters and so on, currently I have
find . -name '*' -depth \
| while read f ;
do
mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr -s ' ' _|tr -d "'"|tr -d ","|tr - _|tr "&" "y"|tr "@" "a")" ;
done
Is there any way to do the tr stuff above and the iconv at a single run? because I am talking around 300,000 files to rename, I would like to avoid a second search if possible.
If needed, I am working with Bash 4.2.24
I think the following does everything you want in one pass.
# Update: if this doesn't work, use read -d '' instead
find . -print0 | while IFS= read -d '$\000' f ;
do
orig_f="$f"
# Below is pure bash. You can replace with tr if you like
# f="$( echo $f | tr -d ,\' | tr "$'&'@- " "ya__" )"
f="${f// /_}" # Replace spaces with _
f="${f//\'}" # Remove single quote
f="${f//-/_}" # Replace - with _
f="${f//,}" # Remove commas
f="${f//&/y}" # Replace ampersand with y
f="${f//@/a}" # Replace at sign with a
f=$( iconv -f UTF8 -t ASCII//TRANSLIT <<< "$f" )
new_dir="$(dirname $f)"
new_f="$(basename $f)"
mkdir -p "$new_dir"
mv -i "$orig_f" "$new_dir/$new_f"
done
The find
command (no real options needed, other than -print0
to handle filenames with spaces) will send null-separated file names to the while
loop (and someone will correct my errors there, no doubt). A long list of assignments utilizing parameter expansion removes/replaces various characters; I include what I think is the equivalent pipeline using tr
as a comment. Then we run the filename through iconv
to deal with character set issues. Finally, we split the name into its path and filename components, since we may have to make a new directory before executing the mv
.