我正在寻找一种grep多个原子的方法,例如“foo”和“bar”。
我知道我可以使用
grep 'foo' file | grep 'bar'
得到他们两个但我想知道是否有更有效的方式。任何googleing似乎只会抛出'或'基于搜索的结果,而不是'和'。
答案 0 :(得分: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
答案 1 :(得分:3)
egrep '(foo.*bar|bar.*foo)'
# or
grep -E '(foo.*bar|bar.*foo)'
答案 2 :(得分:1)
这可能有效。 :)由于文件系统级别的缓存,再次加载grep
可能是免费的。并且,假设命中数很少(与输入行数相比),并且包含'foo'的大多数行也将成为'bar'的命中,grep
的第二个实例也没有没什么可做的。