bashはxargs grepを1回だけ検索します


16

多分それは少し奇妙です-そして多分これを行うための他のツールがありますが、まあ..

次の古典的なbashコマンドを使用して、文字列を含むすべてのファイルを検索しています。

find . -type f | xargs grep "something"

複数の深さで、非常に多くのファイルがあります。「何か」が最初に現れるだけで十分ですが、findは検索を続け、残りのファイルを完了するのに長い時間がかかります。私がやりたいのは、grepから検索への「フィードバック」のようなもので、findが他のファイルの検索を停止できるようにすることです。そのようなことは可能ですか?

回答:


20

単にfindの領域内に保管してください:

find . -type f -exec grep "something" {} \; -quit

これがどのように機能するかです:

-execときに動作します-type ftrueになります。また、が一致するとgrep返される0(成功/ true)ため-exec grep "something"-quitがトリガーされます。


8
find -type f | xargs grep e | head -1

まさにそれをします:がhead終了すると、パイプの中間要素は「壊れたパイプ」信号で通知され、順番に終了し、に通知しfindます。次のような通知が表示されます。

xargs: grep: terminated by signal 13

これを確認します。


説明と代替手段として+1を使用しますが、他の答えは私にとってはよりエレガントに見えますが、それはより自給自足的であるためです
-hello_earth

8

ツールを変更せずにこれを行うには:(xargsが大好きです)

#!/bin/bash
find . -type f |
    # xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20
    # grep -m1: show just on match per file
    # grep --line-buffered: multiple matches from independent grep processes
    #      will not be interleaved
    xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >(
        # Error output (stderr) is redirected to this command.
        # We ignore this particular error, and send any others back to stderr.
        grep -v '^xargs: .*: terminated by signal 13$' >&2
    ) |
    # Little known fact: all `head` does is send signal 13 after n lines.
    head -n 1

1
+1は、xargsがそのようなマルチタスク機能を持つことを決して知りませんでした-他のコメントもありがとう!:)
hello_earth 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.