Bash は find -exec を使用して 360,000 個のファイルの名前を変更します

Bash は find -exec を使用して 360,000 個のファイルの名前を変更します

次のようなファイルが約 360,000 個あります:

./001/1/1.jpg
./001/1/2.jpg
./001/2/1.jpg
./002/1/1.jpg
./003/1/1.jpg
...
pattern: [60 dirs]/[1000 subdirs]/[4-10 files].jpg

たとえば、*.jpg から *.jpeg にファイル名を変更したいのですが、引数リストが長すぎるというエラーが発生するため、renamesingle では実行できません。rename

解決策を探して、これを見つけましたが、名前は何も変更されません:

find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's/jpg/jpeg/' {}/* \;

{}rename を echo に置き換えて展開されているかどうかを確認すると、次のようになります。

find -maxdepth 2 -mindepth 2 -type d -exec echo "rename -n 's/jpg/jpeg/' {}/*" \;

期待通りの結果が得られました:

rename -n 's/jpg/jpeg/' ./061/61430/*
rename -n 's/jpg/jpeg/' ./061/61431/*
...

これらの名前変更コマンドのいずれかを実行すると、名前変更は機能します。したがって、 に問題があるはずです{}

ご協力ありがとうございます!

答え1

最初のインスタンスでは、*に到達する前にシェルによって が展開されますrename( が展開されるかどうかはわかりませんが、 に一致するものがあるとは思えません{}/*)。 が展開されない場合、実行されるコマンドは、、renameの 3 つの引数とともに実行されます。 最後の引数は既存のファイルの名前ではないため、何も実行されません。-ns/jpg/jpeg/some/path/*rename

シェルグロブがなければ、パスは役に立ちませんrename

したがって、代わりに次の操作を行ってください。

find -maxdepth 3 -mindepth 3 -type f -iname '*.jpg' -exec rename -n 's/jpg$/jpeg/i' {} +

の代わりに を使用することfindで、可能な限り長いコマンドラインを構築できる の機能を使用します。+;

答え2

find  | prename 's/\.jpg$/.jpeg/'

または現在のディレクトリに別のファイルがある場合

find 0[0-9][0-9] | prename 's/\.jpg$/.jpeg/'

答え3

type dディレクトリ名のみを変更する場合以外は指定しないでください。拡張子を変更する.jpg.jpeg

find . -maxdepth 2 -mindepth 2 -name '*.jpg' -exec sh -c 'echo mv -- "$0" "${0%%.jpg}.jpeg"' {} \;

echo画面に表示されている内容が気に入ったら削除してください。

答え4

Cygwinを使用した私のバージョンのrenameには正規表現の置換がなく、そのrename [options] expression replacement file...構文も機能していないようです。また、bashの提案は失敗します。

... -c: line 0: unexpected EOF while looking for matching `"'
... -c: line 1: syntax error: unexpected end of file

残念なことに... perl は常に存在します:

perl -MFile::Find -e 'find(sub{return unless /^(.*)\.jpg$/;`mv $_ $1.jpeg`}, ".")'

関連情報