计算正则表达式的唯一出现次数

4

我有一份服务器的邮件日志,我想统计每个用户每小时发送了多少封电子邮件。

目前,我已删除了不必要的信息,但我无法让它统计每个唯一用户发送的电子邮件数量。

到目前为止我写的是:

 awk '{print $3, $7;}' ./maillog | sed '/from/!d' | sed 's/:[0-9][0-9]:[0-9][0-9] /:00 /g' | sed 's/from=<//g' | egrep '[a-zA-Z0-9]+\@[a-zA-Z0-9.-]+(org|net|com)' | uniq -c > output.txt

主要问题是我发现同一个用户在同一小时内出现多次(我不希望出现这种情况)。需要得到的示例可以在此处查看:http://1drv.ms/1AwMMzQ。请注意,我需要的示例只是一个样例,而非正确的输出结果。如果您在我所提供的文件上运行脚本,将会在同一小时内两次记录用户25,这并不满足要求。以下是某人建议的输出示例(非常长):
Jan 16 08:33:04 mail.knurledwidgets.example.org sendmail[3539]: q5c1SrFqkAZq9b: Milter: connect to filters
Jan 16 08:33:06 mail.knurledwidgets.example.org sendmail[3539]: q5c1SrFqkAZq9b: from=<user1@dont-cross-the-memes.example.com>, size=38065260, class=-30, nrcpts=1, msgid=<gnDSaYSEaP4Yk/.F0EhYbIYcihGO8Vd.dont-cross-the-memes.example.com>, proto=ESMTP, daemon=MTA-v6, relay=proton.dont-cross-the-memes.example.com [192.168.98.234]
Jan 16 08:33:06 mail.knurledwidgets.example.org sendmail[7734]: qqGjhufuNY5UJ: Milter: connect to filters
Jan 16 08:33:07 mail.knurledwidgets.example.org sendmail[8780]: qkwEbHuoJi40Lj: Milter: connect to filters
Jan 16 08:33:07 mail.knurledwidgets.example.org sendmail[8780]: qkwEbHuoJi40Lj: from=<user25@knurledwidgets.example.org>, size=36412443, class=-30, nrcpts=1, msgid=<w/7AIsHSy6.gkNTPlyyE55u.knurledwidgets.example.org>, proto=ESMTP, daemon=MTA-v6, relay=mail.knurledwidgets.example.org [10.0.0.20]
Jan 16 08:33:08 mail.knurledwidgets.example.org sendmail[7734]: qqGjhufuNY5UJ: from=<user6@stellar-patrol.example.com>, size=33411319, class=-30, nrcpts=1, msgid=<il/5SxUES9XwRhX.KfO6ywkQROALbnz.stellar-patrol.example.com>, proto=ESMTP, daemon=MTA-v6, relay=feinstein.stellar-patrol.example.com [192.168.73.3]
Jan 16 08:33:09 mail.knurledwidgets.example.org sendmail[3539]: q5c1SrFqkAZq9b: Milter accept: message
Jan 16 08:33:09 mail.knurledwidgets.example.org sendmail[8780]: qkwEbHuoJi40Lj: Milter accept: message
Jan 16 08:33:10 mail.knurledwidgets.example.org sendmail[7734]: qqGjhufuNY5UJ: Milter accept: message
Jan 16 08:33:12 mail.knurledwidgets.example.org sendmail[1618]: qhgKT0cN80gSX: Milter: connect to filters
Jan 16 08:33:13 mail.knurledwidgets.example.org sendmail[1618]: qhgKT0cN80gSX: from=<user25@knurledwidgets.example.org>, size=780642, class=-30, nrcpts=1, msgid=<hX49btAurMDDZlhWo.5RpGEJxQQilElvDgRpc3sw.knurledwidgets.example.org>, proto=ESMTP, daemon=MTA-v6, relay=mail.knurledwidgets.example.org [10.0.0.20]

以下是输出示例的样本:
1 08:00 user10@yuhoo.example.com
1 08:00 user19@knurledwidgets.example.org
1 08:00 user1@beshonk.example.com
5 08:00 user27@knurledwidgets.example.org
1 09:00 user12@knurledwidgets.example.org
1 09:00 user17@knurledwidgets.example.org
1 09:00 user26@knurledwidgets.example.org
7 09:00 user27@knurledwidgets.example.org
2 09:00 user33@knurledwidgets.example.org
1 09:00 user42@knurledwidgets.example.org

请解释一下你给出的答案,因为目的是学习而不是做练习。
谢谢你的时间。

在问题本身中包含一小部分输入和期望输出的示例将非常有用。 - Tom Fenech
我添加了样本,但输入格式混乱,基本上每行都以“Jan”开头(为了澄清)。 - Petru Daniel Tudosiu
1
我假设那是一个所需输出的示例? - merlin2011
很遗憾,我们没有得到期望的输出结果,只是为了让我们感受一下期望的输出结果而给出的。 - Petru Daniel Tudosiu
很遗憾,它不存在...那就为我们制作一个吧! - Tom Fenech
显示剩余2条评论
1个回答

2

sort命令在uniq之前可以给出计数:

awk '{print $3, $7;}' ./maillog | sed '/from/!d' | sed 's/:[0-9][0-9]:[0-9][0-9] /:00 /g' | sed 's/from=<//g' | egrep '[a-zA-Z0-9]+\@[a-zA-Z0-9.-]+(org|net|com)' | sort | uniq -c`

  1 08:00 user1@dont-cross-the-memes.example.com>,
  2 08:00 user25@knurledwidgets.example.org>,
  1 08:00 user6@stellar-patrol.example.com>,

请参考 uniq --help

注意:除非重复的行是相邻的,否则 uniq 不会检测到它们。 您可能需要先对输入进行排序,或使用不带 uniqsort -u。 此外,比较遵循由 LC_COLLATE 指定的规则。


请问你能解释一下为什么吗?这和uniq有关吗?谢谢! - Petru Daniel Tudosiu
uniq 的文档应该说明只有“连续”的行才会被计算,并且可能需要排序才能得到所需的结果... - Has QUIT--Anony-Mousse

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