【问题标题】:Applying multiple regexes in awk在 awk 中应用多个正则表达式
【发布时间】:2012-10-24 13:58:11
【问题描述】:

我有一个很大的日志文件。我必须一个一个地应用多个正则表达式,在打印每个正则表达式的输出之前,我需要打印一些文本。

例如。

应用正则表达式后,我应该得到如下输出:

Text 1

Output of first regex
....


Text 2 

Output of second regex
....

Text 3

Output of third regex
....

其中文本 1、文本 2 和文本 3 是我插入的文本。我们可以使用 AWK 实现这一点吗?

编辑:

我正在添加示例日志文件的一部分。

[1351059075] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
[1351059898] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
[1351073883] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL 
[1351073886] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL
[1351088949] SERVICE ALERT: server3:PSU ;CRITICAL;HARD;3;Connection refused

现在我想分离所有EmailHistoryPSU,所以我的输出应该是这样的:

Email:

[1351059075] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
[1351059898] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused

History:

[1351073883] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL 
[1351073886] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL

PSU:

[1351088949] SERVICE ALERT: server3:PSU ;CRITICAL;HARD;3;Connection refused 

我写了一个简单的 awk 脚本:

awk 'BEGIN {print "Email:\n\n"} /SERVICE ALERT: .*Email.*CRITICAL;HARD/ {print $0}' logfilename

我不知道如何在同一个 awk 脚本中包含多个正则表达式以便以所需的方式打印。

【问题讨论】:

  • 是的,您可以使用 awk 实现这一目标,但我们不知道如何为您提供帮助。请包括简化的样本数据,以及基于该样本数据的所需输出。还包括您尝试执行的代码、错误消息或输出不满足您要求的原因的描述。祝你好运。
  • @shellter:添加了所需的数据。

标签: linux awk


【解决方案1】:

您要求做的是微不足道的(只需添加更多 /RE/{action} 行),但您使用 RE 的方法首先是错误的。您需要做的就是:

$ cat file
[1351059075] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
[1351059898] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
[1351073883] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL
[1351073886] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL
[1351088949] SERVICE ALERT: server3:PSU ;CRITICAL;HARD;3;Connection refused

$ cat tst.awk
BEGIN{ FS = "[:;]" }
{ out[$3] = out[$3] $0 ORS }
END { for (type in out) print type ORS out[type] }

$ awk -f tst.awk file
Email
[1351059075] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
[1351059898] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused

PSU
[1351088949] SERVICE ALERT: server3:PSU ;CRITICAL;HARD;3;Connection refused

History
[1351073883] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL
[1351073886] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL

【讨论】:

    【解决方案2】:

    尝试以下命令(在不同的行中进行单行拆分):

    awk '
        BEGIN { 
            FS = "[:;]"; 
        } 
        {
            if ( $3 in keys ) {
                printf "%s\n", $0;
            }
            else {
                printf "%s%s:\n\n%s\n", (length( keys ) > 0) ? "\n" : "", $3, $0;
            }
    
            keys[ $3 ] = 1;
        }
    ' infile
    

    产生:

    Email:
    
    [1351059075] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
    [1351059898] SERVICE ALERT: server1:Email;CRITICAL;HARD;3;Connection refused
    
    History :
    
    [1351073883] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL 
    [1351073886] SERVICE ALERT: server2:History ;CRITICAL;HARD;3;HTTP CRITICAL
    
    PSU :
    
    [1351088949] SERVICE ALERT: server3:PSU ;CRITICAL;HARD;3;Connection refused
    

    【讨论】:

    • 一些问题:1) 行尾的分号添加空语句,而不是终止行,2) 使用 length(array) 使其特定于 GNU awk,3 )您不应该将 1 分配给 keys[$3] ,因为如果不这样做,您会更清楚地创建一个集合,并且 4)测试集合中存在的值的惯用 awk 方法是使用 keys[ $3]++ 作为条件,而不是在一行中测试它,然后再填充它。
    • @EdMorton: 1) 我不明白你在第一点是什么意思。 2) 你确定length 不适用于awk 的非GNU 版本吗?它出现在其手册页中。 3) keys[ $3 ] = 1 在该程序中是必需的,因为我只想在第一行打印标题,并将其用作标志。 4) 是的,我不习惯这种表达方式,但看起来好多了。下次我会努力记住的。
    • 1) 在 C "foo;" 中表示“do foo”,因为“;”s terminate 语句,但在 awk 中它表示“do foo”,然后是“do nothing”——它是 2 个独立的不相关语句。 2) 是的。它也可能在 tawk 中工作,但不再可供下载。您可能正在阅读 gawk 手册页。尝试在命令行中添加“--posix”标志。 3)您将“keys”作为一个集合使用 - 将您的行更改为“keys[$3]”而没有分配,您会发现它仍然有效,但代码意图更清晰。 4) 好的。
    • 澄清 '1)" - 在 awk 中写“foo;”就像在 C 中写“foo;;”一样。你可以这样做,它会编译但它是错误的。
    • @EdMorton:好的。谢谢你。我测试了这两点。带有--posixlength 函数仅适用于字符串,不适用于数组:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多