【问题标题】:Count unique occurrence of a regex计算正则表达式的唯一出现次数
【发布时间】:2015-04-17 13:42:39
【问题描述】:

我有一个maillog 的服务器,我想计算每个用户每小时发送多少封电子邮件。

目前我删除了所有不需要的信息,但我无法计算每个唯一用户发送的电子邮件数量。

到目前为止我写的是:

 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

主要问题是(我相信)我在同一小时内多次找到同一个用户(我不希望这样)。

Here 是我需要得到的。请注意,我需要获得的只是一个示例,并不是我应该拥有的正确输出。如果你在我给你的文件上执行我写的脚本,你会在同一小时内获得2次user25,不满足要求。

这是有人建议的输出示例(很长):

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

还请解释您给出的答案,因为目的是学习而不是做练习。

感谢您的宝贵时间

【问题讨论】:

  • 在问题本身中包含一小部分输入和所需输出会很有用。
  • 我添加了样本,遗憾的是输入的格式搞砸了,基本上每一行都以 Jan 开头(为了澄清)。
  • 我假设这是期望输出的样本?
  • 遗憾的是,我们没有得到想要的输出,它只是为了让我们感觉得到想要的输出。
  • 可惜不是...那就为我们做一个吧!

标签: regex linux bash shell


【解决方案1】:

uniq 之前的 sort 会给你计数:

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 不会检测重复行,除非它们是相邻的。 您可能希望首先对输入进行排序,或者使用sort -u 而不使用uniq。 此外,比较遵循LC_COLLATE 指定的规则。

【讨论】:

  • 您能解释一下原因吗?它与 uniq 有什么关系?谢谢!
  • uniq 的文档应该说明只计算 连续 行,并且可能需要排序才能产生所需的结果...
猜你喜欢
  • 2021-12-31
  • 2012-08-04
  • 2021-01-23
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多