GNU/Linux >> Linux の 問題 >  >> Linux

無効なエンコードを含むファイルの名前を一括変更する方法、または無効なエンコード文字を一括置換する方法は?

あなたが望んでいたものではないことはわかっていますが、元のエンコーディングがわかっている場合は、おそらく convmv を使用できます エンコーディングを UTF-8 に変更すると、ほとんどの問題が解決します。

これは、無効にエンコードされたポーランド語のファイル名を含むフォルダーで機能しました:

convmv -f cp1250 -t utf8 -r .

このコマンドは実際には何も名前を変更しないことに注意してください。 --notest を追加 ファイルの名前を実際に変更するオプション。


ファイルの名前を変更したい場合、いくつかの問題が発生します。および 同時にディレクトリ。ファイルの名前だけを変更するのは簡単です。ただし、ディレクトリの名前も変更されていることを確認する必要があります。単純に mv Motörhead/Encöding Motorhead/Encoding することはできません Motorhead以降 呼び出し時には存在しません。

そのため、すべてのファイルとフォルダーを深さ優先で走査し、現在のファイルまたはフォルダーのみの名前を変更する必要があります。以下は GNU find で動作します 私のOS Xでは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 を保証します 出力は null で区切られているため、read -d '' で読み取ることができます file に 変数。そうすることで、スペースや改行を含む、あらゆる種類の奇妙なファイル名に対処することができます。
  • dirname でファイルのディレクトリを取得します .常に変数を適切に引用符で囲むことを忘れないでください。そうしないと、パスにスペースやグロブ文字が含まれていると、このスクリプトが壊れてしまいます。
  • basename で実際のファイル名 (またはディレクトリ名) を取得します .
  • 次に、$f から無効な文字を削除します Bash の文字列置換機能を使用します。無効とは、小文字または大文字、数字、スラッシュ (\/) 以外のものを意味します。 )、ドット (\. )、アンダースコア、またはマイナス ハイフン。
  • If $f 既にクリーンな場合 (クリーンな名前は現在の名前と同じです)、スキップしてください。
  • If $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


    Linux
    1. Linuxでファイルの名前を変更する方法

    2. 文字を再帰的にsedに置き換える方法は?

    3. ファイル名から無効な文字を削除するには?

    1. Linuxでgocryptfsを使用してファイルを暗号化する方法

    2. LinuxでファイルをUTF-8エンコーディングに変換する方法

    3. Linuxでファイルを解凍する方法(例付き)

    1. 検索を使用して複数のファイルの名前を変更するにはどうすればよいですか?

    2. パターンを使用してファイルのセットの名前を変更するにはどうすればよいですか?

    3. Linux シェルを使用してスペースを含むファイルの名前を変更するにはどうすればよいですか?