Bash - 指定された正規表現パターンを含むすべてのファイルの名前を変更する

Bash - 指定された正規表現パターンを含むすべてのファイルの名前を変更する

ディレクトリ内に、文字列「HG-U133A」または「HG-U133B」のいずれかを含むファイルがいくつかあります。ディレクトリ内のすべてのファイルを調べて、すべての「HG-U133A」ファイルの名前を「A_」プレフィックスに変更し、すべての「HG-U133B」ファイルの名前を「B_」プレフィックスに変更するスクリプトを作成したいと思います。

これらが私のディレクトリにあるファイルだとすると

> grep "HG-U133[AB]" *
fileA.txt: HG-U133A
fileB.txt: HG-U133A
fileC.txt: HG-U133B
fileD.txt: HG-U133A
fileE.txt: HG-U133B

これらのファイルの名前を変更できるスクリプトを書きたいのですが

> ls
A_fileA.txt
A_fileB.txt
B_fileC.txt
A_fileD.txt
B_fileE.txt

これについて助けていただけると本当にありがたいです。ありがとうございます

答え1

これは、Bashの落とし穴その1

for file in *; do
  [ -f "$file" ] || continue
  grep -q -- HG-U133A "$file" && { mv -- "$file" "A_$file"; continue; }
  grep -q -- HG-U133B "$file" && mv -- "$file" "B_$file"
done

ノート:

  • *ドットファイルには一致しませんが、grep呼び出しで使用したので、その動作が適切であるか、変更方法を知っているものと思われます。
  • *ディレクトリと一致します。 は、grepディレクトリを処理する可能性のあるオプションなしで呼び出されました。 スクリプトは通常のファイル以外のものをすべてスキップします。 その主な目的は、ディレクトリをスキップして、grepそれらの実行を煩わしくしないことです (いずれにしても失敗します)。
  • 二重ダッシュ(--)については、次のとおりです。--(ダブルダッシュ) とはどういう意味ですか? (「裸のダブルダッシュ」とも呼ばれます)これは、ファイル名のいずれかがダッシュで始まる場合のためです。./*の代わりにを使用した場合*、これは必要ありません。
  • あなたは「どちらか…または…」と言いましたが、私はこれを「特定のファイルに対して最大で 1 つの文字列が一致する」と解釈します。したがって、continue最初の の後に、2 番目を無駄にgrep呼び出さないようにするためにあります。grep
  • を含むファイルが多くHG-U133B、 を含むファイルが少ないことが予想される場合はHG-U133A、まず をテストすることを検討してくださいHG-U133B

利点:

  • 携帯性、
  • 堅牢性 (コードはファイル名に関係なく正常に動作するはずです)。

不利益:

  • 通常のファイルごとに少なくとも 1 つのgrepプロセスを生成することは最適とは言えません。検査するファイルの数が多い場合は、処理速度が低下する可能性があります。

答え2

次のコマンドでbash実行できます。

for file in `grep -l HG-U133A *` ; do mv "$file" "A_$file" ; done
for file in `grep -l HG-U133B *` ; do mv "$file" "B_$file" ; done

関連情報