如何从Bash中用iconvrecursion重命名文件和文件夹

我一直试图recursion重命名文件和文件夹与iconv没有成功,文件被正确地重命名,但文件夹不要。

我使用的文件是(作品完美):

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

我试过的文件和文件夹(失败:只重命名文件夹):

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

原来的问题:我只是想批量重命名大量的文件,使他们“networking友好”,认为像删除空间,怪异的人物等,目前我有

 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 

有没有办法做到上面的tr的东西和iconv在一个单一的运行? 因为我正在谈论30万个左右的文件来重命名,所以我想尽量避免再次search。

如果需要,我正在使用Bash 4.2.24

提前致谢。

我想下面的一切都是你想要的。

 # 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 

find命令(不需要真正的选项,除了-print0来处理带有空格的文件名)将发送null分隔的文件名到while循环(有人会纠正我的错误,毫无疑问)。 一大堆使用参数扩展的分配将删除/替换各种字符; 我使用tr作为注释,包括我认为是等价的管道。 然后我们通过iconv运行文件名来处理字符集问题。 最后,我们把这个名字分解成它的路径和文件名组件,因为在执行mv之前我们可能不得不建立一个新的目录。

chepner的答案是避免嵌套错误。 使用tacfind的输出反转到文件夹本身之前的文件夹内容上。 这样,就不需要mkdir了:

 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." 

请享用 ;)