4

ファイルとフォルダーの名前を 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)"' -- {} \;

元の問題:多くのファイルの名前を一括して「ウェブフレンドリー」にしたいだけで、スペースや奇妙な文字などを削除するように考えていますが、現在私は持っています

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 を一度に実行する方法はありますか? 名前を変更するファイルが約 300,000 個あるので、できれば 2 回目の検索は避けたいと思います。

必要に応じて、Bash 4.2.24 を使用しています。

前もって感謝します。

4

2 に答える 2

3

以下は、1回のパスで必要なすべてを実行すると思います。

# 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。.

于 2012-07-17T21:00:12.840 に答える