How to rename files and folder with iconv recursively from Bash

I am trying to recursively rename files and folders with an icon without success, the files have been renamed correctly, but the folders will not.

What I use for files (works fine):

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

What I tried for files and folders (crash: only rename folders):

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

ORIGINAL problem: I just want to rename a lot of files to make them "web friendly", thinks how to remove spaces, strange characters, etc., I currently 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 make tr file higher and iconv in one go? because I say about 300,000 files to rename, I would like to avoid a second search, if possible.

If necessary, I work with Bash 4.2.24

Thanks in advance.

+4
source share
2 answers

I think the following does everything you need in one go.

 # 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 (no real parameters except -print0 for handling file names with spaces) will send null file names to the while (and someone will correct my errors there, no doubt). A long list of assignments using the parameter extension removes / replaces various characters I include what I consider the equivalent pipeline using tr as a comment. Then we run the file name through iconv to solve the character set problems. Finally, we split the name into its path and the components of the file name, since we may need to create a new directory before executing mv .

+2
source

Here is the update I offer after chepner's answer to avoid nesting errors. Cancel the output of find on tac to affect the contents of the folders in front of the folders themselves. Thus, mkdir no longer needed:

 echo "renaming:" find . -print0 | tac -s '' | while IFS= read -d '' f ; do Odir=$(dirname "$f") # original location Ofile=$(basename "$f") # original filename newFile=$Ofile # remove unwanted characters newFile=$(echo $newFile | tr -d ",'\"?()[]{}\\!") newFile="${newFile// /_}" # Replace spaces with _ newFile="${newFile//&/n}" # Replace ampersand with n newFile="${newFile//@/a}" # Replace at sign with a newFile=$( iconv -f UTF8 -t ASCII//TRANSLIT <<< "$newFile" ) if [[ "$Ofile" != "$newFile" ]]; then # act if something has changed echo "$Odir/$Ofile to" echo "$Odir/$newFile" mv -i "$Odir/$Ofile" "$Odir/$newFile" echo "" fi done echo "done." 

Enjoy;)

0
source

All Articles