使用 grep 与 awk

hol*_*asz 23 linux performance grep awk

要捕获特定模式,awk并且grep可以使用。为什么我们应该使用一个?哪个更快,为什么?

如果我有一个日志文件并且我想获取某个模式,我可以执行以下操作之一

awk '/pattern/' /var/log/messages
Run Code Online (Sandbox Code Playgroud)

或者

grep 'pattern' /var/log/messages
Run Code Online (Sandbox Code Playgroud)

我没有做过任何基准测试,所以我不知道。有人可以详细说明吗?很高兴了解这两个工具的内部工作原理。

Dra*_*oan 28

grep 很可能会更快:

# time awk '/USAGE/' imapd.log.1 | wc -l
73832

real    0m2.756s
user    0m2.740s
sys     0m0.020s

# time grep 'USAGE' imapd.log.1 | wc -l
73832

real    0m0.110s
user    0m0.100s
sys     0m0.030s
Run Code Online (Sandbox Code Playgroud)

awk 是一种解释型编程语言,而 grep 是一种编译后的 c 代码程序(它还针对在文件中查找模式进行了优化)。

(注意 - 我运行了两次命令,以便缓存不会潜在地扭曲结果)

有关维基百科解释性语言的更多详细信息。

正如 Stephane 在评论中正确指出的那样,您的里程可能会因您使用的 grep 和 awk 的实现、它所在的操作系统以及您正在处理的字符集而异。

  • 无需说明您正在使用什么 grep 或 awk 实现,在什么计算机体系结构上,以及使用哪个系统字符集,这些时间没有什么价值。 (3认同)
  • 有趣的是,使用 BSD 工具(在 Mac 上),awk(31.74s)比 sed(33.34s)略快,后者比 grep(34.21s)略快。Gnu awk 在 5.24 秒拥有它们,我没有 gnu grep 或 sed 来测试。 (2认同)
  • grep 应该稍微快一点,因为 awk 对每个输入行所做的不仅仅是在其中搜索正则表达式,例如,如果在脚本中引用了一个字段(在这种情况下不是这样)awk 将根据字段分隔符值并填充内置变量。但是与您发布的内容几乎没有区别。到目前为止 **grep 和 awk wrt 匹配正则表达式之间最重要的区别是 grep 搜索整行以查找匹配字符串,而 awk 可以搜索特定字段,因此提供更高的精度和更少的错误匹配。 (2认同)

Use*_*ess 15

使用最具体和最具表现力的工具。最适合您的用例的工具可能是最快的。

作为一个粗略的指南:

  • 搜索与子字符串或正则表达式匹配的行?使用 grep。
  • 从简单分隔的文件中选择某些列?使用切。
  • 执行基于模式的替换或... sed 可以合理地做的其他事情?使用 sed。
  • 需要上述 3 的某种组合,或 printf 格式,或通用循环和分支?使用awk。

  • @sds 不,除非您要做文本处理以外的其他事情,否则您不需要 perl。awk 非常适用于比 grep/cut/sed 更复杂的文本处理内容,并且作为奖励是所有 UNIX 安装的标准配置,与 perl 不同。 (5认同)
  • @RetroCode:python比perl更“通用”;等效的一句台词可能会更长。 (2认同)

slm*_*slm 13

当只搜索字符串并且速度很重要时,您几乎应该总是使用grep. 它比awk粗略搜索要快几个数量级。

source sed、awk 和其他 Unix 解析实用程序的功能和性能差异

UTILITY    OPERATION TYPE      EXECUTION TIME     CHARACTERS PROCESSED PER SECOND
                               (10 ITERATIONS)
-------    --------------      ---------------    -------------------------------
grep       search only         41 sec.            489.3 million
sed        search & replace    4 min. 4 sec.      82.1 million
awk        search & replace    4 min. 46 sec.     69.8 million
Python     search & replace    4 min. 50 sec.     69.0 million
PHP        search & replace    15 min. 44 sec.    21.2 million
Run Code Online (Sandbox Code Playgroud)

  • 对于 grep 只是搜索而它们也在替换的其他实用程序来说,这并不公平。 (2认同)
  • 这些完全是假数字。谈论比较苹果和橙子 - 这就像说你 ** 只能** 在网站 A 上在 5 秒内找到一辆新车,而你可以找到一辆车,协商价格,获得贷款,然后在网站 B 上购买汽车在 1 小时内,因此站点 A 比站点 B 快。您引用的文章在 grep、sed 和 awk 之间的相对执行速度的陈述中完全错误,并且还说“awk ...具有正则表达式的 PCRE 匹配”这是完全不真实的。 (2认同)

Sté*_*las 6

虽然我同意理论上grep应该比awkYMMV快,但实际上 YMMV 在很大程度上取决于您使用的实现。

这里比较了busybox 1.20.0的grep和awk、GNU grep 2.14、mawk 1.3.3、GNU awk 4.0.1在Debian/Linux 7.0 amd64(带有glibc 2.17)上的UTF-8语言环境中的2.5M行的240MB文件仅 ASCII 字符。

$ time busybox grep error error | wc -l
331003
busybox grep error error  8.31s user 0.12s system 99% cpu 8.450 total
wc -l  0.07s user 0.11s system 2% cpu 8.448 total
$ time  busybox awk /error/ error | wc -l
331003
busybox awk /error/ error  2.39s user 0.84s system 98% cpu 3.265 total
wc -l  0.12s user 1.23s system 41% cpu 3.264 total
$ time  grep error error | wc -l
331003
grep error error  0.80s user 0.10s system 99% cpu 0.914 total
wc -l  0.00s user 0.11s system 12% cpu 0.913 total
$ time mawk /error/ error | wc -l
330803
mawk /error/ error  0.54s user 0.13s system 91% cpu 0.732 total
wc -l  0.03s user 0.08s system 14% cpu 0.731 total
$ time gawk /error/ error | wc -l
331003
gawk /error/ error  1.37s user 0.12s system 99% cpu 1.494 total
wc -l  0.04s user 0.07s system 7% cpu 1.492 total
$ time 
Run Code Online (Sandbox Code Playgroud)

在 C 语言环境中,只有 GNU grep 得到了显着的提升并且变得比mawk.

数据集,正则表达式的类型也可能有很大的不同。对于正则表达式,awk应该与grep -Easawk的正则表达式进行比较。

对于这个数据集,awk可能比grep基于 busybox 的系统或mawk默认awk和默认语言环境是基于 UTF-8 的系统(IIRC,它曾经是 Ubuntu 中的情况)更快。