【问题标题】:Grep multiple strings on large filesGrep 大文件上的多个字符串
【发布时间】:2013-07-04 17:41:27
【问题描述】:

我有大量的大型日志文件(每个日志文件大约 200mb,我总共有 200GB 数据)。

每 10 分钟,服务器向日志文件写入大约 10K 参数(带有时间戳)。在每 10K 参数中,我想将其中的 100 个提取到一个新文件中。

首先我使用带有 1 个参数的 grep,然后 LC_ALL=C 让它更快一点,然后我使用 fgrep 它也稍微快一点。然后我用并行

parallel -j 2 --pipe --block 20M

最后,对于每 200MB,我能够在 5 秒内提取 1 个参数。

但是.. 当我在一个 grep 中管道多个参数时

parallel -j 2 --pipe --block 20M "egrep -n 'param1|param2|...|param100" < log.txt

然后 grep 操作的时间线性增加(现在 grep 1 文件需要相当多的时间)。 (请注意,我必须将 egrep 用于多个管道,不知何故 grep 不喜欢它们)。

有没有更快/更好的方法来解决这个问题?

请注意,我不需要使用正则表达式,因为我正在寻找的模式是固定的。我只想提取包含特定字符串的某些行。

【问题讨论】:

  • 试过fgrep -f pattern_file 吗? Fgrep 从 pattern_file 中获取固定字符串。不要尝试 - 但值得一试。
  • 所以当您仔细阅读日志文件时,您不想进行全面扫描,对吗?仅最后一次写入就足够了吗?你有时间戳的模式吗?你能限制你的搜索吗?这是一个选择吗?
  • @jm666 是的,我也尝试了 fgrep -f 但它只提高了 0.03 秒。
  • @JS웃 是的,我有一个关于时间戳的模式,但我想要对这些日志文件进行全面扫描。

标签: bash unix logging grep large-files


【解决方案1】:

为了反映上述 cmets,我进行了另一项测试。从md5deep -rZ 命令获取我的文件(大小:319MB)。随机选择 100 个 md5 校验和(每个 32 个字符长)。

time egrep '100|fixed|strings' md5 >/dev/null

时间

real    0m16.888s
user    0m16.714s
sys     0m0.172s

time fgrep -f 100_lines_patt_file md5 >/dev/null

时间到了

real    0m1.379s
user    0m1.220s
sys     0m0.158s

几乎是 egrep 的 15 倍。

所以,当您在 egrepfgrep 恕我直言时仅获得 0.3 秒的改进时:

  • 你的 IO 变慢了

egrep 的计算时间不会因处理器或内存而减慢,而是因 IO 和(恕我直言)而减慢,因此 fgrep 不会提高速度。

【讨论】:

  • 就我而言,对于单个字符串,fgrep 甚至比 egrep 花费更多时间。 (pattern.txt 只有 1 个字符串)。时间并行 -j 2 --pipe --block 20M "fgrep -f pattern.txt" /dev/null 真实 0m4.904s 用户 0m9.074s sys 0m2.398s 时间并行 -j 2 --pipe - -block 20M "egrep -f pattern.txt" /dev/null real 0m4.861s user 0m8.955s sys 0m2.394s
  • 感谢您的回答。我将文件压缩成 .gz 格式并使用 zgrep。它工作得非常快。
【解决方案2】:

有趣的是,将日志文件压缩为 .gz 格式并使用 zgrep -E 大大减少了时间。此外,我在单个 zgrep 命令中搜索 1 个模式还是多个模式都没关系,它只在每个 200MB 文件大约 1 秒左右工作。

【讨论】:

  • 压缩文件需要多长时间?那不可能是免费的,......或者可以;-? ...祝大家好运。
  • 我已经把这些文件压缩了,所以我不确定:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
  • 2013-12-27
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多