find -exec:{}と+の間にパラメータを追加する

find -exec:{}と+の間にパラメータを追加する

findを使用してファイルを見つけてディレクトリにコピーしたいので、次のようにします。

find . -name '*.png' -exec cp {} /tmp/dest +

しかしこれは失敗する

find: missing argument to `-exec'

+それをaに置き換えると機能します;が、cpは各ファイルに対して個別に呼び出されます。フォームを使用する+ときに末尾のパラメータ(ターゲットディレクトリなど)をどのように追加しますか-exec

もちろん、この場合は、cp -t次のようにして明らかな制限を解決できます。スタックオーバーフローに関するこの記事しかし、その解決策はcp.の代わりにrsync、scp、または他のツールを使用します。{}+の間にパラメータを追加する一般的な方法はありますかfind -exec

ベストアンサー1

いいえ、使用すると空白以外に-exec ... {} +何も残らない可能性があります。この問題を解決する方法はありません。{}+

POSIX標準仕様でfindコマンド:

-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +

注記の終わりは、<semicolon>aまたはaで句読点を取る必要があります<plus-sign><plus-sign>2 つの文字のみを含む引数の後にある場合にのみ、{}メイン式の末尾を句読点としてマークする必要があります。他の用途は<plus-sign>特別な用途と見なされるべきではありません。

より一般的な解決策は次のとおりです。

find ... -exec sh -c 'cp "$@" /tmp/dest' sh {} +

ここで、sh -cインラインスクリプトはのバッチパラメータを使用して実行されますfind。インラインスクリプトの中には、渡され"$@"たパラメータのリスト(個別に引用)があり、それを使用してcp任意の方法でコマンドラインに配置できます。

これにより、GNU以外cp(例えば、オプションのないmacOSや他のBSDシステム-t)やfind

関連:


誰もこれを要求しなかったが、とにかく…

ターゲットディレクトリを変数に入れますdestdir

destdir=/tmp/dest

find ... -exec sh -c 'destdir=$1; shift; cp "$@" "$destdir"' sh "$destdir" {} +

シェルからの呼び出しはdestdirスクリプトとはfind別の変数です。destdirsh -c

または以下を使用してbash

destdir=/tmp/dest

find ... -exec bash -c 'cp "${@:2}" "$1"' bash "$destdir" {} +

これは、ターゲットディレクトリパス名を別の変数に抽出するのではなく、コマンドライン"$@"に合わせてリストを適切に並べ替えるためにリストを「断片化」することです。cp$1

おすすめ記事