"find/-name '*.txt' | cp /junk"が機能しないのはなぜですか?

名前に.txtを含むファイルを見つけて、見つかった一致ごとに/junkフォルダにコピーするには、次の方法を使用することをお勧めします。

find / -name "*.txt" | cp /junk

ただし、findはリスト形式で結果を生成し、そのリストをcpに入力できないため、これは機能しません。

したがって、xargsを使用してこの問題を解決できます。

find / -name "*.txt" | xargs cp /junk

xargsはリストを1行に変更するので、cpに入力できます。私はまた、このコマンドがファイル検索を完全に完了し、「リストの作成」を完了した後にのみパイプラインの右側(コピー)を実行すると思いました。

あるいは、(好ましくは)execを使用することができます。

find / -name ".txt" -exec cp {} /junk \;

一致するものが見つかるたびにコピーが実行されます(別のプロセスで実行されるため、findコマンドは引き続き並列に実行されます)。

誰かがこのコマンドと私の理解が正しいことを確認できますか?

これは教育目的にすぎず、実際のシナリオではないことを付け加えたいと思います。

ベストアンサー1

  1. はい、標準入力から引数を読み取らないため、機能find / -name "*.txt" | cp /junkしません。cp
  2. いいえ、stdinから読み込まれた引数がコマンドに追加され、間違った方向にコピーしようとしているfind / -name "*.txt" | xargs cp /junkため、それも機能しません。 (オプションを使用して問題を解決できますが、単に使用することもできます。)xargscp-Ixargsfind -exec
  3. はい、find / -name ".txt" -exec cp {} /junk \;うまくいきます。しかし、ファイルごとに1回の呼び出しを使用しますcp(そしてファイルが見つかるとコマンドが実行されます)。

このソリューションを試してみることもできます。 1回の呼び出しのみを開始する必要がありますcp(または少なくとも限られたコマンドライン長でできるだけ少ない呼び出しを開始します)。

find / -path /junk -prune -or -name '*.txt' -print0 | xargs -0 sh -c 'cp "$@" /junk'

cp -t@don_chrisstiが述べたように、GNU cpがあれば使用できます。だからあなたはこれを行うことができます

find / -path /junk -prune -or -name '*.txt' -print0 | xargs -0 cp -t /junk

でも

find / -path /junk -prune -or -name '*.txt' -exec cp -t /junk {} +

どちらもコマンドラインからできるだけ多くの引数を収集し、できるだけ少ないインスタンスを実行しますcp。ただし、cpaが完了する前に開始される可能性はまだあるため、findこれを除外する必要があります。/junkそれ以外の場合は、コピーを見つけることができます。

おすすめ記事