【问题标题】:About awk shell and pipe in linux关于 linux 中的 awk shell 和 pipe
【发布时间】:2012-01-18 11:20:33
【问题描述】:

大家,我正在处理一个大约有 500 万行的日志文件,所以我在 linux 中使用 awk shell

我必须 grep 域并获得日志中最高的 100,所以我这样写:

          awk '{print $19}' $1 | 
          awk '{ split($0, string, "/");print string[1]}' |
          awk '{domains[$0]++} END{for(j in domains) print domains[j], j}' |
          sort -n | tail -n 100 > $2

运行大约 13 秒

然后我像这样更改脚本:

          awk 'split($19, string, "/"); domains[string[1]]++}
               END{for(j in domains) print domains[j], j}' $1 |
          sort -n | tail -n 100 > $2

运行大约 21 秒

为什么?

你知道awk shell的一行可能会减少cal的总和,它只读取每一行一次,但是时间增加了......

所以,如果你知道答案,请告诉我

【问题讨论】:

  • 您的输入数据是什么样的?你想提取和保存什么信息??
  • +1 用于提问、研究和格式化!您是否多次运行此程序,也许有一个高 CPU 任务正在运行以竞争第二次运行?否则,我同意@rjack 的观点,即拆分工作可以提高性能。祝你好运:-)
  • 它运行在具有以下信息的 linux 服务器上:cpu: 8 * Intel(R) Xeon
  • 我跑了很多次,而且我的任务有时间限制,所以我很关心运行时间。

标签: linux shell awk


【解决方案1】:

当您使用管道命令时,只要管道已满,它们就会并行运行。

所以我的猜测是,在第一个版本中,工作分布在你的 CPU 中,而在第二个版本中,所有工作都由一个内核完成。

您可以使用top(或者,更好的是htop)来验证这一点。


出于好奇,这样更快吗? (未经测试):

cut -f 19 -d' ' $1 | cut -f1 -d'/' | sort | uniq -c | sort -nr | head -n 100 > $2

【讨论】:

  • 我希望它会更慢,因为sort 步骤会占用大量内存(我预计它是物理内存在 500 万行时),而 awk 仅涉及大约 Number_of_different_domains * (sizeof(number) + average_sizeof_domain)
  • 我还是有点迷茫。你知道第二个 awk 的输入是第一个 awk 的输出,它们必须是有序的,它们是如何并行运行的?管道有多大?第二个 awk 开始处理未完成的输入???
  • "第二个 awk 开始处理未完成的输入???"是的,awk 逐行读取,因此只要管道中有一行或多行,第二次调用就可以开始工作。 OTOH,sort 需要读取其所有输入,这会破坏管道。
猜你喜欢
  • 2013-09-27
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多