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
別の変数です。destdir
sh -c
または以下を使用してbash
:
destdir=/tmp/dest
find ... -exec bash -c 'cp "${@:2}" "$1"' bash "$destdir" {} +
これは、ターゲットディレクトリパス名を別の変数に抽出するのではなく、コマンドライン"$@"
に合わせてリストを適切に並べ替えるためにリストを「断片化」することです。cp
$1