\ ; / + . < > -
私は小さな会社で IT を担当していますが、私の厳しい警告にもかかわらず、先頭と末尾のスペース、不適切な文字 (など)を含むひどい名前のファイルをサーバーに置きます。
彼らは、Mac 上の AFP 経由で (FreeBSD/FreeNAS) サーバーにアクセスすることでこれを実行するため、システムのどの部分もエラーを発生しません。
ディレクトリ ツリー全体を調べて不正なファイル名を修正するために使用できるスクリプトはありますか?
基本的に、すべてのスペースと不正な ASCII を_
... に置き換え、ファイルがすでに存在する場合は、_2
最後に a または何かを追加します。
システムを強制する適切なファイル名の命名規則はありますか?
ありがとう!
答え1
私は bash と find を使用します。もっと簡単な方法があると思いますが、私が思いついた方法は次のとおりです。
これは「/」を含むファイル名を扱うことができます(findは警告を出しますが、無視してください)が、現在のディレクトリ内のファイルに対してのみ機能します(サブディレクトリなし)。ファイル名の「/」とパスの一部である「/」を bash または find に区別させる方法がわかりませんでした。
for i in $(find . -maxdepth 1 -type f -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" | sed 's/\.\///'); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}; done
これですできない「/」を含むファイル名を処理しますが、現在のディレクトリ内のすべてのファイルで機能します。およびそのサブディレクトリ:
for i in $(find . -type f -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%]/_}; done
必ず実行する前にこれらをテストしてください私が実行したいくつかのテストでは問題なく動作しましたが、網羅的ではありませんでした。また、私は Linux システムを使用していることに留意してください。find やおそらく bash の特定の実装は、お使いのシステムによって異なる場合があります。
編集:mv $i
コマンドを `mv -i $i' に変更すると、既存のファイルを上書きする前に mv がプロンプトを表示します。
編集2: スペースを含むファイル名を処理するには、bash IFS (入力フィールドセパレータ) 変数を次のように変更します (ここ):
SAVEIFS=$IFS; IFS=$(echo -en "\n\b"); for i in $(find . -type f -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%\ ]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%\ ]/_}; done; IFS=$SAVEIFS
また、正規表現を変更して、スペースをアンダースコアに一致/置換するようにしました。SAVEIFS ビットは、IFS 変数を元の構成に戻すだけです。
説明:
for i in $(command); do something $i; done
これは一般的な bash ループです。コマンドの出力を調べ、コマンドによって返された各値を変数 $i に順番に設定し、それに対して何らかの処理を行います。
find . -maxdepth 1 -type f -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" '
現在のディレクトリ内で、名前に次のいずれかの文字が含まれるすべてのファイルを検索します: :;><@$#&()\/%
。さらに追加するには、それらを "\" (例 "\¿") でエスケープし、括弧 ([ ]) 内のリストに追加します。おそらく、これらの文字すべてをエスケープする必要はありませんが、どの環境でどの文字が特殊変数であるかを覚えておくことはできないため、念のためすべてをエスケープします。
sed 's/\.\///
find の出力から現在のディレクトリを削除し、「./foo」の代わりに「foo」を出力します。
mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}
この小さなスクリプトがループするたびに、$i は不適切な名前のファイルの名前になります。このコマンドは、そのファイルを移動 (名前変更) し、不要な文字をすべて "_" に変更します。詳細については、bash の置換を調べてください。