ディレクトリ構造に対して再帰的に何かを行うコマンドは次のfind
とおりです。
find . -name "*.jpg" -exec bash -c 'file="{}"; cp "$file" "${file%%.jpg}1.jpg"' \;
-exec
の代わりに使用するfor i in $(find ...)
と、スペースを含むファイル名が処理されます。もちろん、引用の落とし穴はまだ 1 つあります。ファイル名に が含まれている場合"
、file="{}"
は に展開されますがfile="name containing "quote characters""
、これは明らかに壊れています (file
になりname containing quote
、コマンドを実行しようとしcharacters
ます)。
そのようなファイル名がある場合、またはその可能性がある場合は、 を使用して null 文字 (ファイル名では許可されていません) で区切られた各ファイル名を出力し-print0
、 を使用while read -d $'\0' i
して null で区切られた結果をループします。
find . -name "*.jpg" -print0 | \
(while read -d $'\0' i; do cp "$i" "${i%%.jpg}1.jpg"; done)
このような複雑なコマンドと同様に、何も実行せずにテストして、実行する前に意味のあるものに展開されていることを確認することをお勧めします。これを行う最善の方法は、実際のコマンドの前に を追加することecho
です。そのため、実行する代わりに、実行されるコマンドが表示されます。
find . -name "*.jpg" -print0 | \
(while read -d $'\0' i; do echo cp "$i" "${i%%.jpg}1.jpg"; done)
目で見て結果が良さそうに見えたら、 を削除しecho
て再度実行し、実際に実行します。