web-dev-qa-db-ja.com

find-execを使用してBashで360000ファイルの名前を変更

私は次のような約360000のファイルを持っています:

./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

renameを使用して、たとえば* .jpgから* .jpegにファイルの名前を変更したいと思います。エラー引数リストが長すぎるため、単一の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/*
...

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

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

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

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

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

最初の例では、*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の機能を使用してください。

4
muru

renameが欠落している場合の別の方法は、次のとおりです。

find 0[0-6][0-9] -name "*.jpg" -exec sh -c 'for i do echo mv "$i" "${i%g}eg"; done' sh {} + 
1
jlliagre

Cygwinを使用すると、私のバージョンの名前変更には正規表現の置換がなく、その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`}, ".")'
0
Lucas

ディレクトリのみの名前を変更する場合を除いて、type dを指定しないでください。拡張子を.jpgから.jpegに変更するには

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

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

0
jimmij