ファイルとディレクトリの名前を同時に変更する場合は、いくつかの問題が発生します。ファイルのみの名前変更は簡単です。ただし、ディレクトリの名前も変更する必要があります。あなたは、単にすることができないmv Motörhead/Encöding Motorhead/Encoding
ので、Motorhead
呼び出しの時点で存在しません。
そのため、すべてのファイルとフォルダーの深さ優先走査を必要とし、現在のファイルまたはフォルダーのみを名前変更します。以下find
は、私のOS X上のGNU およびBash 4.2.42で動作します。
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
new="${f//[\\\/\:\*\?\"<>|]/}"
Windowsで処理できないものを置き換える場合は、を使用して正規表現を変更できます。
このスクリプトをとして保存しrename.sh
、で実行可能にしchmod +x rename.sh
ます。次に、のように呼び出しますrename.sh /some/path
。
ファイル名の衝突(“ Notice
”アナウンス)を必ず解決してください。
あなたがいるなら絶対に確認してくださいそれは右の置換を行い、削除echo
、実際にそれが何を印刷するのではなく、物事の名前を変更するスクリプトから。
安全のために、まずファイルの小さなサブセットでこれをテストすることをお勧めします。
オプションの説明
ここで何が起こるかを説明するには:
-depth
ディレクトリが深さ優先で再帰されるようにするため、最後からすべてを「ロールアップ」できます。通常、find
トラバースは異なります(ただし、幅優先ではありません)。
-print0
確実にfind
我々がそれを読むことができるように、出力は、ヌルで区切られているread -d ''
にfile
変数。そうすることで、スペースや改行を含む、あらゆる種類の奇妙なファイル名に対処できます。
- でファイルのディレクトリを取得します
dirname
。変数を常に適切に引用することを忘れないでください。そうしないと、スペースまたはグロブ文字を含むパスがこのスクリプトを破壊します。
- で実際のファイル名(またはディレクトリ名)を取得します
basename
。
- 次に、
$f
Bashの文字列置換機能の使用から無効な文字を削除します。無効とは、小文字、大文字、数字、スラッシュ(\/
)、ドット(\.
)、アンダースコア、マイナスハイフン以外のものを意味します。
$f
既にクリーンな場合(クリーンな名前は現在の名前と同じです)、スキップします。
$new
ディレクトリに既に存在する場合$d
(例えば、あなたが名前のファイルを持っているresume
し、résumé
同じディレクトリに)、警告を発行します。一部のシステムでmv foo foo
は問題が発生するため、名前を変更したくありません。さもないと、
- 最後に、元のファイル(またはディレクトリ)の名前を新しい名前に変更します
これが唯一の最も深い階層に作用しますので、名前を変更するMotörhead/Encöding
にはMotorhead/Encoding
2つの段階で行われます。
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
これにより、すべての交換が正しい順序で行われます。
サンプルファイルとテスト実行
と呼ばれるベースフォルダ内のいくつかのファイルを仮定しましょうtest
:
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
デバッグモードでの実行(のecho
前mv
)からの出力、つまり呼び出されるコマンドと衝突警告は次のとおりです。
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
メッセージがないことを注意してくださいwith-hyphen.txt
、schedule
とtest
自分自身。
mv
(1)既にクリーンなファイルがある場合(結果としてmv foo foo
)、または(2)を除く同じ名前のファイルがある場合に発生する可能性がある、既に存在する宛先のケースを処理するロジックを追加することができます特殊文字(たとえば、に加えてmv Encöding Encoding
既にEncoding
ファイルがある場合Encöding
)。