3

「foo」や「bar」など、複数のアトムをgrepする方法を探しています。私は
grep 'foo' file | grep 'bar'
それらの両方を取得するために使用できることを知っていますが、もっと効率的な方法があるかどうか疑問に思いました。グーグルは、「and」ではなく「or」ベースの検索の結果のみをスローするようです。

4

3 に答える 3

5

あなたが選択した方法よりも効率的な方法が得られるとは思えません。2番目のコピーが実行されたときにgrep実行可能ファイルがすでにメモリにマップされており、正規表現にバックトラッキングがないことを考えると(egrep 'foo.*bar|bar.*foo'明らかな解決策とは異なり)、得られるものは速いと思います。

ポイントを説明するためのサンプルタイミングを次に示します。

allan@allan-desktop:~$ time egrep 'foo.*bar|bar.*foo' foobar | wc -l
2000
real 0m0.006s
user 0m0.004s
sys  0m0.004s

allan@allan-desktop:~$ time fgrep 'foo' foobar | fgrep 'bar' | wc -l
2000
real 0m0.039s
user 0m0.000s
sys  0m0.000s

allan@allan-desktop:~$ time egrep 'foo.*bar|bar.*foo' foobar | wc -l
2000
real 0m0.006s
user 0m0.004s
sys  0m0.008s

allan@allan-desktop:~$ time fgrep 'foo' foobar | fgrep 'bar' | wc -l
2000
real 0m0.005s
user 0m0.004s
sys  0m0.004s

この確かに小さなサンプルから、パイプライン バージョンはシステムとユーザーの CPU 時間が少なくて済むため、より効率的です。

入力ファイルは、次の 1000 個のコピーで構成されます。

foo-bar
bar-dgfjhdgjhdgdfgdjghdjghdfg-foo

独自のテストを実行できます。

彼女は 100,000 行の入力を使用した同じテストです。質問者の方法がより効率的であることがわかります。

allan@allan-desktop:~$ time egrep 'foo.*bar|bar.*foo' foobar | wc -l
    100000
    real 0m0.135s
    user 0m0.136s
    sys  0m0.012s
allan@allan-desktop:~$ time fgrep 'foo' foobar | fgrep 'bar' | wc -l
    100000
    real 0m0.034s
    user 0m0.048s
    sys  0m0.012s
allan@allan-desktop:~$ time egrep 'foo.*bar|bar.*foo' foobar | wc -l
    100000
    real 0m0.151s
    user 0m0.144s
    sys  0m0.000s
allan@allan-desktop:~$ time fgrep 'foo' foobar | fgrep 'bar' | wc -l
    100000
    real 0m0.046s
    user 0m0.044s
    sys  0m0.012s
于 2008-12-03T12:21:46.700 に答える
3
egrep '(foo.*bar|bar.*foo)'
# or
grep -E '(foo.*bar|bar.*foo)'
于 2008-12-03T12:08:14.700 に答える
1

これは効率的かもしれません。:)grepファイルシステムレベルでのキャッシュにより、再ロードはおそらく無料です。また、ヒット数が(入力の行数と比較して)少なく、「foo」を含むほとんどの行が「bar」でもヒットすると仮定すると、の2番目のインスタンスにgrepは多くはありません。する。

于 2008-12-03T12:09:24.637 に答える