快速grep / grep仅适用于行号?

时间:2012-09-16 23:34:48

标签: linux search grep

我正在寻找grep的帮助,或grep之类的工具。这包括但不限于grep,egrep,awk,sed或用于搜索匹配的其他工具。但我会在剩下的问题上称之为grep。

我正在寻找为匹配文件grep文件的快速方法,我也在寻找最快的方法来为匹配文件grep文件,并且只返回其中的行号而不是匹配行的其余部分。我不介意语法是否复杂,只要速度快,我将在程序复杂性中使用它不是问题。

如果我需要regex的模式,我也需要这个方法,所以我也可以搜索范围。因此,如果我需要搜索少于10的所有数字,如果默认支持它,或者如果它需要一些正则表达式,我只是寻找我能找到的最快方法。

谢谢。

修改

我正在使用的文件非常大,我的测试文件是1.9gb

5 个答案:

答案 0 :(得分:5)

我认为KingsIndian使用grep的-m选项,但如果速度是您的主要目标,cut可能比awk更快地用于此特定用途。尝试:

grep -n -m 1 regex file | cut -d: -f1

-d:参数告诉cut使用冒号作为字段分隔符,而-f1参数告诉它只输出第一个字段。

答案 1 :(得分:3)

在第一场比赛后停止:

grep -n -m 1 str file | awk -F: '{print $1}'

您可以将m的参数值更改为其他值,以便在多次匹配后停止。 awk部分仅限于行号。

在5场比赛后停止:

grep -n -m 5 str file | awk -F: '{print $1}'

修改
您可以使用tail。例如,要跳过前5个匹配并打印下一个7:grep -n -m 12 str file| tail -7 | awk -F: '{print $1}'

答案 2 :(得分:1)

我不确定这是否很快,但这似乎有效:

nl -b a "<filename>" | grep "<phrase>" | awk '{ print $1 }'

答案 3 :(得分:1)

您可以使用GNU awk进行模式匹配,只需打印出行号:

awk '/regex/ { print NR }' file.txt

假设值以空格分隔,如果行包含小于10的数字,则可以找到行号:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) print NR }' file.txt

然而,这将打印每次出现的小于10的数字的行号。我相信您可能会发现这不合需要。因此,要为每个匹配删除多个重复的行号,可以使用数组:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (i in array) print i }' file.txt

如果您需要排序输出,请输入sort -n。如果您更喜欢更优雅的解决方案(即没有管道):

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (j in array) sorted[k++]=j+0; n = asort(sorted); for (j=1; j<=n; j++) print sorted[j] }' file.txt

修改

在上述最后三个awk命令中,只需将if ($i <= 10)更改为if ($i >= 11 && $i <= 20)即可显示11到20的结果。

答案 4 :(得分:1)

我刚刚用一个非福的sed调用进行了一些测试并且不幸运,但是在这里参考带有1千兆字节文本文件的数字,其中我的$ PATTERN是最后一行的一部分:

(剧透:grep在此操作上快5倍以上,awk最慢)

user@box:~$ ls -lh /dev/shm/test 
-rw-r--r-- 1 user user 979M Jul  8 09:50 /dev/shm/test
user@box:~$ sed --version | head -n1
GNU sed-Version 4.2.1
user@box:~$ time sed -n "/$PATTERN/{=;q}" /dev/shm/test
206558

real    0m6.835s
user    0m6.160s
sys 0m0.648s
user@box:~$ grep -V | head -n1
grep (GNU grep) 2.14
user@box:~$ time grep -n -m 1 "$PATTERN" /dev/shm/test | cut -d: -f1
206558

real    0m1.337s
user    0m0.592s
sys 0m0.736s
user@box:~$ awk --version | head -n1
GNU Awk 4.0.1
user@box:~$ time awk "/$PATTERN/ { print NR }" /dev/shm/test
206558

real    0m7.176s
user    0m6.356s
sys 0m0.776s