私はdebianサーバーを持っており、インターネットラジオ局の音楽をホストしています。多くのファイルに無効なエンコーディングが含まれているため、ファイル名とパスに問題があります。次に例を示します。
./music/Bändname - Some Title - additional Info/B�ndname - 07 - This Title Is Cörtain, The EncÃDing Not.mp3
理想的には、文字以外のすべてを削除したいA-Z
/a-z
または数字0-9
またはダッシュ-
/アンダースコア_
...結果は次のようになります。
./music/Bndname-SomeTitle-additionalInfo/Bndname-07-ThisTitleIsCrtain,TheEncdingNot.mp3
多くのファイルとディレクトリのバッチでこれを達成するにはどうすればよいですか?
私はこの同様の質問を見ました: 特殊文字を含むファイルの一括名前変更(または正しく表示)
しかし、これはエンコーディングを修正するだけなので、上記のように、より厳密なアプローチを好みます。
ファイルとのディレクトリの名前を同時に変更したい場合、いくつかの問題が発生します。ファイルの名前を変更するのは簡単です。ただし、ディレクトリの名前も変更する必要があります。 Motorhead
は呼び出し時に存在しないため、単純にmv Motörhead/EncöDing Motorhead/Encoding
することはできません。
したがって、すべてのファイルとフォルダーの縦型検索を行ってから、現在のファイルまたはフォルダーのみの名前を変更する必要があります。以下は、OS XのGNU find
および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
Windowsが処理できないものを置き換える場合は、new="${f//[\\\/\:\*\?\"<>|]/}"
を使用して正規表現を変更できます。
このスクリプトをrename.sh
として保存し、chmod +x rename.sh
で実行可能にします。次に、rename.sh /some/path
のように呼び出します。
ファイル名の競合をすべて解決してください(「Notice
」アナウンス)。
絶対に確実が正しい置換を行う場合は、スクリプトからecho
を削除して、実際の名前を変更するだけでなく、実際の名前を変更します。
安全のために、最初にファイルの小さなサブセットでこれをテストすることをお勧めします。
ここで何が起こっているかを説明するには:
-depth
を使用すると、ディレクトリが深さ優先で再帰的に再実行されるため、最後からすべてを「ロールアップ」できます。通常、find
は異なる方法でトラバースします(幅優先ではありません)。-print0
は、find
出力がヌル区切りであることを保証するため、read -d ''
を使用してfile
変数に読み込むことができます。そうすることで、スペースのあるファイル名や改行を含む、あらゆる種類の奇妙なファイル名を処理するのに役立ちます。dirname
でファイルのディレクトリを取得します。常に変数を適切に引用することを忘れないでください。そうしないと、スペースまたはグロビング文字を含むパスがこのスクリプトを壊します。basename
で取得します。$f
から無効な文字を削除します。無効とは、小文字または大文字、数字、スラッシュ(\/
)、ドット(\.
)、アンダースコア、またはマイナスハイフン以外のものを意味します。$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
自体のメッセージがないことに注意してください。
私はそれがあなたが望んだものではないことを知っていますが、元のエンコーディングがわかっている場合は、おそらく convmv
を使用してエンコーディングをUTF-8に変更できます。これにより、ほとんどの問題が修正されます。
これは、無効にエンコードされたポーランド語ファイル名がいくつかあるフォルダーで私にとってはうまくいきました:
convmv -f cp1250 -t utf8 -r .
このコマンドは実際には何も名前を変更しないことに注意してください。追加 --notest
オプションを使用して、ファイルの名前を実際に変更します。
私は知っています、あなたは名前の変更について尋ねました。
しかし、 MusicBrainz Picard のようなソフトウェアを使用すると、問題を簡単に回避できます。
音楽を識別(オーディオフィンガープリント)し、巨大な MusicBrainz データベースから必要なすべてのデータ(利用可能な場合はカバー画像を含む)をダウンロードし、ファイルを移動して、コレクションを任意のパターンに合わせることができます。お気に入り。私は何年も使用していますが、常にキリリックからアラビア語まで完璧に機能しました。もちろん(少なくともラテン語ベースのスクリプトの場合)、ASCIIへの変換も可能です。
このアプローチでは、ファイルが読み取り可能で完全なものである限り、コレクションの名前がどれほど厄介で悪意のあるものであるかは問題ではありません。
(私はそれが無料だと言いましたか?言論の自由とビールの両方のように?ソフトウェアとデータベースの両方..?)