>以降は利用できないexec '{}'を探す

>以降は利用できないexec '{}'を探す

Execを使用すると、すべてのパラメータを一度に渡す{} +か、次を使用して1つずつ渡すことができます。{} \;

それでは、すべての名前を変更したいとしましょう。JPEG、これを行うには問題はありません。

find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec mv '{}' '{}'.new \;

ただし、出力をリダイレクトする必要がある場合は、'{}'リダイレクト後にアクセスできません。

find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec cjpeg -quality 80 '{}' > optimized_'{}' \;

これはうまくいきません。 forループを使用してfindを使用する前に、出力を変数に保存する必要があります。現実を直視すると、それは面倒なことです。

for f in `find . \( -name '*.jpg' -o -name '*.jpeg' \)`; do cjpeg -quality 80 $f > optimized_$f; done;

それでは、より良い方法がありますか?

答え1

bash -cコマンドで使用find -execし、bashコマンドで位置引数を使用できます。

find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} \;

{}この方法が提供されます$1

sh{}ここで使用される文字列は、内部シェルに「名前」を通知する前のエラーメッセージに使用されます。これについては、以下でさらに詳しく説明します。stackoverflowに対するこの回答

答え2

答えがあります(https://unix.stackexchange.com/a/481687/4778)、しかしそれが理由です。

リダイレクト>、パイピング、|および$拡張はすべて、コマンドを実行する前にシェルで実行されます。したがって、optimized_{}始める前にstdoutがにリダイレクトされます。find

答え3

現在のシェルがそれを解釈するのを防ぐには、リダイレクトが必要です。
ただし、これを引用すると、コマンドの出力がリダイレクトされるのを防ぐことができます。
既知の解決策はシェルを呼び出すことです。

find . -name '*.jpg' -exec sh -c 'echo "$1" >"$1".new' called_shell '{}' \;

この場合、リダイレクト(>)は現在のシェルで参照され、呼び出しシェル内で正常に動作します。サブシェル()の引数(名前)として使用されますcalled_shell$0sh

ファイル名にサフィックスを追加するとうまく機能しますが、プレフィックスを使用するとうまく機能しません。プレフィックスが機能するようにするには、./ファイル名の前の検索を削除して${1#./}その-execdirオプションを使用する必要があります。

-inameこのオプションを使用して、*.JPG名前が付けられたファイルや他のバリエーションのあるファイルも含めることも、そうでない場合もあります。*.JpG

find . \( -iname '*.jpg' -o -iname '*.jpeg' \) -execdir sh -c '
     cjpeg -quality 80 "$1" > optimized_"${1#./}"
     ' called_shell '{}' \;

for f do … ; done最後にループ()とaを追加して、ファイルごとに1回ではなく、ディレクトリごとに1回シェルを呼び出すことも、そうでない場合もあります。+

find . \( -iname '*.jpg' -o -iname '*.jpeg' \) -execdir sh -c '
     for f; do cjpeg -quality 80 "$f" > optimized_"${f#./}"; done
     ' called_shell '{}' \+

最後に、cjpegファイルに直接書き込むことができれば、リダイレクトは防止されます。

find . \( -iname '*.jpg' -o -iname '*.jpeg' \) -execdir sh -c '
     for f; do cjpeg -quality 80 "$f" -outfile optimized_"${f#./}"; done
     ' called_shell '{}' \+

答え4

スクリプトcjq80を生成します。

#!/bin/bash
cjpeg -quality 80 "$1" > "${1%/*}"/optimized_"${1##*/}"

実行可能にする

chmod u+x cjq80

-execで使用してください。

find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec cjq80 '{}' \;

関連情報