3

我正在寻找一种方法来 grep 多个原子,例如“foo”和“bar”。我知道我可以用
grep 'foo' file | grep 'bar'
它们来获得它们,但我想知道是否有更有效的方法。任何谷歌搜索似乎都只会抛出基于“或”的搜索结果,而不是“和”。

4

3 回答 3

5

我怀疑你会得到比你选择的更有效的方法。鉴于 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' 的命中数,第二个实例grep不会有很多做。

于 2008-12-03T12:09:24.637 回答