如何使用 awk 从特定客户端提取 Postfix 日志中的所有对话?

发布于 2024-09-10 14:55:08 字数 1870 浏览 7 评论 0原文

我正在尝试根据发起对话的客户端从 Postfix 日志文件中提取对话。这是提取匹配消息 ID 的 awk 脚本:

awk '/client.host.name/ && !(/timeout/||/disconnect/) { sub(":","",$6);print $6}' maillog

这是使用标准 Postfix 邮件日志作为输入(请参阅下面的示例数据)。我认为我想要做的是使用第一次搜索的结果对文件进行多次搜索,但我不确定这是否是正确的方法。类似于:

awk '/client.host.name/ && !(/timeout/||/disconnect/) {sub(":","",$6);msgid=$6} $0 ~ msgid {print $0}' maillog

但是,自然,这是行不通的正如预期的那样。我假设我需要执行以下操作之一:

  1. 将第一个 awk 的输出通过管道传输到第二个 awk 或 grep (不知道如何使用管道输入作为正则表达式)。
  2. 将第一个结果集分配给一个数组,并使用该数组作为搜索集。类似于:
    awk '/app02/ && !(/timeout/ || /connect/) { sub(":","",$6);msgid[$6]=$6; } END { for(x in msgid) { print x; } }' 邮件日志
    但我不确定如何在 for 循环中进行。 awk 有没有办法“倒带”文件,然后抓取与数组中任何元素匹配的所有行?
  3. 放弃整个交易并尝试使用 Perl。

那么,对于 awk 专家来说...有什么方法可以使用 awk 来完成我正在寻找的任务吗?

样本数据:

Jul 19 05:07:57 relay postfix/smtpd[5462]: C48F6CE83FA: client=client.dom.lcl[1.2.3.4]
Jul 19 05:07:57 relay postfix/cleanup[54]: C48F6CE83FA: message-id=<[email protected]>
Jul 19 05:07:57 relay postfix/qmgr[12345]: C48F6CE83FA: from=<[email protected]>, size=69261, nrcpt=6 (queue active)
Jul 19 05:08:04 relay postfix/smtp[54205]: C48F6CE83FA: to=<[email protected]>, relay=in.example.org[12.23.34.5]:25, delay=0.7, delays=0.05/0/0.13/0.51, dsn=2.0.0, status=sent (250 ok: Message 200012345 accepted)
Jul 19 05:14:08 relay postfix/qmgr[12345]: C48F6CE83FA: removed`

I am trying to extract conversations from a Postfix log file based on the client that initiated them. This is the awk script that extracts the matching message IDs:

awk '/client.host.name/ && !(/timeout/||/disconnect/) { sub(":","",$6);print $6}' maillog

This is using a standard Postfix maillog as input (see below for sample data). What I think I'd like to do is a multi-pass search of the file using the results of the first search, but I'm not sure if this is the right approach. Something similar to:

awk '/client.host.name/ && !(/timeout/||/disconnect/) {sub(":","",$6);msgid=$6} $0 ~ msgid {print $0}' maillog

But, naturally, this doesn't work as expected. I'm assuming I need to do one of the following things:

  1. Pipe the output from the first awk into a second awk or grep (not sure how to use piped input as a regex).
  2. Assign the first result set to an array and use the array as a search set. Something like:
    awk '/app02/ && !(/timeout/ || /connect/) { sub(":","",$6);msgid[$6]=$6; } END { for(x in msgid) { print x; } }' maillog
    I'm not sure how I'd proceed inside the for loop though. Is there a way in awk to "rewind" the file and then grab all lines that match any element within an array?
  3. Scrap the whole deal and try it using Perl.

So, for the awk gurus... is there any way to accomplish what I'm looking for using awk?

Sample data:

Jul 19 05:07:57 relay postfix/smtpd[5462]: C48F6CE83FA: client=client.dom.lcl[1.2.3.4]
Jul 19 05:07:57 relay postfix/cleanup[54]: C48F6CE83FA: message-id=<[email protected]>
Jul 19 05:07:57 relay postfix/qmgr[12345]: C48F6CE83FA: from=<[email protected]>, size=69261, nrcpt=6 (queue active)
Jul 19 05:08:04 relay postfix/smtp[54205]: C48F6CE83FA: to=<[email protected]>, relay=in.example.org[12.23.34.5]:25, delay=0.7, delays=0.05/0/0.13/0.51, dsn=2.0.0, status=sent (250 ok: Message 200012345 accepted)
Jul 19 05:14:08 relay postfix/qmgr[12345]: C48F6CE83FA: removed`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

从来不烧饼 2024-09-17 14:55:08

您可以使用数组。大致是这样的:

awk '/client.host.name/ && !(/timeout/||/disconnect/) {sub(":","",$6);msgid[$6]=1} {if ($FIELD in msgid) print}' maillog

您必须替换包含数据的字段编号,因为我不知道它。

编辑:移动了左大括号。

Edit2:

这是特定于您的示例数据的版本:

awk '/client.dom.lcl/ && !(/timeout/||/disconnect/) {sub(":","",$6); msgid[$6] = 1} {if (gensub(":", "", 1, $6) in msgid) print}' sampledata

Edit2:

这是一个简化版本:

awk '{id = gensub(":", "", 1, $6)} /client.dom.lcl/ && !(/timeout/||/disconnect/) {msgid[id] = 1} {if (id in msgid) print}' sampledata

You can use an array. Something roughly like this:

awk '/client.host.name/ && !(/timeout/||/disconnect/) {sub(":","",$6);msgid[$6]=1} {if ($FIELD in msgid) print}' maillog

Where you'll have to substitute the field number which contains the data since I don't know it.

Edit: Moved a left brace.

Edit2:

Here's a version specific to your sample data:

awk '/client.dom.lcl/ && !(/timeout/||/disconnect/) {sub(":","",$6); msgid[$6] = 1} {if (gensub(":", "", 1, $6) in msgid) print}' sampledata

Edit2:

Here's a simplified version:

awk '{id = gensub(":", "", 1, $6)} /client.dom.lcl/ && !(/timeout/||/disconnect/) {msgid[id] = 1} {if (id in msgid) print}' sampledata
一个人的夜不怕黑 2024-09-17 14:55:08

你要求 awk 但我有一个 perl 脚本,它更强大一点:https://github.com/brablc/postfix-tools/blob/master/pflogrep

您可以使用 is 作为 grep:

pflogrep [email protected] /var/log/maillog

或者您可以将输出提供给 < code>pflogsumm 并获得不错的统计数据:

pflogrep [email protected] /var/log/maillog | pflogsumm

You ask for awk but I have a perl script which is little more robust: https://github.com/brablc/postfix-tools/blob/master/pflogrep

You can use is as grep:

pflogrep [email protected] /var/log/maillog

Or you can feed the output to pflogsumm and get nice statistics:

pflogrep [email protected] /var/log/maillog | pflogsumm
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文