web-dev-qa-db-ja.com

FINDの結果をCOPYコマンドCPにパイプすることは可能ですか?

findの結果をCOPYコマンドcpにパイプすることは可能ですか?

このような:

find . -iname "*.SomeExt" | cp Destination Directory

私はいつもこの種の式を見つけます この投稿などから

find . -name "*.pdf" -type f -exec cp {} ./pdfsfolder \;

これはいくつかの質問を引き起こします:

  1. なぜ|パイプ?それは何のためではないのですか?
  2. なぜ誰もが-exec
  3. パイプでexec()をいつ使用するかを知るにはどうすればよいですか|
21
Paul

良い質問!

  1. なぜ使用できないのですか?パイプ?それは何のためではないのですか?

もちろん、パイプすることもでき、xargsは次の場合に行われます。

find . -iname "*.SomeExt" | xargs cp Destination_Directory/
  1. なぜ誰もが-execを推奨するのですか

-execは、実行内容を正確に制御できるため、優れています。パイプするときはいつでも、コーナーケースで問題が発生する可能性があります。スペースや改行などを含むファイル名です。

  1. パイプを介して(exec)を使用するタイミングを知る方法| ?

それは本当にあなた次第であり、多くの場合があります。私は使うだろう -exec実行するアクションが単純な場合。私はxargsのあまり良い友達ではありません。find出力がwhileループに提供されるアプローチを好む傾向があります。

while IFS= read -r result
do
    # do things with "$result"
done < <(find ...)

cpにはほとんど使用されないオプションがあります:-t destination-manページを参照してください:

find . -iname "*.SomeExt" | xargs cp -t Directory
19
glenn jackman

以下のように_|_を使用できます。

_find . -iname "*.SomeExt" | while read line
do
  cp $line DestDir/
done
_

あなたの質問に答える:

  • _|_を使用して、この問題を解決できます。しかし、上記のように、多くのコードが含まれています。さらに、_|_は2つのプロセスを作成します。1つはfind用、もう1つはcp用です。

  • 代わりにfind内でexec()を使用すると、単一のプロセスで問題が解決されます。

8
Fazlin

これを試して:

find . -iname "*.SomeExt" **-print0**  | xargs **-0** cp -t Directory

ファイル名に空白がある場合。

1
epetrov

ファイル名にスペースがある場合は、以下を試してください。

find . -iname *.ext > list.txt
cat list.txt | awk 'BEGIN {a="'"'"'"}{print "cp "a$0a" Directory"}' > script.sh
sh script.sh

list.txtの前にscript.shおよびsh script.shを検査できます。その後、list.txtscript.shを必ず削除してください。

かっこ付きのファイルがいくつかあり、進行状況バーが必要だったので、cat行を次のように置き換えました。

cat list.txt | awk -v X='"' '{print "rsync -Pa "X$0X" /Volumes/Untitled/"}' > script.sh

0
Toani