关于Linux中的awk shell和pipe

3

大家好,我正在处理一个有大约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的总和,它只读取每行一次,但时间会增加...

因此,如果你知道答案,请告诉我。


你的输入数据是什么样子的?你想要提取和保存哪些信息? - Kent
2
你运行过这个程序超过一次吗?也许有一个高CPU任务在第二次运行时竞争资源。否则,我同意@rjack的观点,将任务分解可以提高性能。祝好运 :-) - shellter
它运行在一个Linux服务器上,该服务器具有以下信息:CPU:8 * Intel(R) Xeon。 - Flypig
我已经运行了很多次,而且我的任务有时间限制,所以我非常关注运行时间。 - Flypig
1个回答

3

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

因此,我猜测在第一个版本中,工作被分配到您的多个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)_的内存。 - ninjalj
我还有点困惑。你知道第二个 awk 的输入是第一个 awk 的输出,它们必须按顺序运行,但是它们如何并行运行?管道有多大?第二个 awk 从哪里开始处理未完成的输入??? - Flypig
第二个 awk 开始处理未完成的输入 ???。是的,awk 逐行读取,因此只要管道中有一行或多行,第二次调用就可以开始工作。另一方面,sort 需要读取所有输入,这会破坏管道。 - Giacomo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接