Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk 如何处理匹配模式之间的字段?_Awk - Fatal编程技术网

Awk 如何处理匹配模式之间的字段?

Awk 如何处理匹配模式之间的字段?,awk,Awk,相关职位: @fedorqui,感谢您为awk提供所有这些不同的选项。在对oom进行故障排除时,我一直在使用它来解析var日志消息,效果非常好。我想进一步扩展,但我还没有弄清楚如何继续。我想做的是: 打印rss和内存不足之间的行。我已经用这个例子做到了 按rss字段对每个匹配项之间的节进行排序。我一直没能弄明白这一点 添加一个具有自己标题的额外列,并执行一些数学运算。我已经能够做到这一点,但我遇到了一些格式问题。我不知道在添加列时如何跳过第一行和最后一行,因此我丢失了这些行。如果我进行打印以外的

相关职位:

@fedorqui,感谢您为awk提供所有这些不同的选项。在对oom进行故障排除时,我一直在使用它来解析var日志消息,效果非常好。我想进一步扩展,但我还没有弄清楚如何继续。我想做的是:

  • 打印rss和内存不足之间的行。我已经用这个例子做到了

  • 按rss字段对每个匹配项之间的节进行排序。我一直没能弄明白这一点

  • 添加一个具有自己标题的额外列,并执行一些数学运算。我已经能够做到这一点,但我遇到了一些格式问题。我不知道在添加列时如何跳过第一行和最后一行,因此我丢失了这些行。如果我进行打印以外的任何操作,我也无法保持与原件的间距

  • 下面是我现在使用的命令:

    less /var/log/messages'|awk '/swapents/{x=1; print "=================="};/Out of memory/{x=0} x'|sed 's/[]\[]//g'
    
    以下是源数据:

    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.617265  pid    uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.622250  1828     0  1828     4331      116      14       3        0         -1000 udevd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.627310  2664     0  2664    28002       53      23       3        0         -1000 auditd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.633181  2680     0  2680    62032     1181      24       4        0             0 rsyslogd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.638888  2694     0  2694     3444       61      11       3        0             0 irqbalance
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.644912  2710    81  2710     5430       56      14       3        0             0 dbus-daemon
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.651108  2779     0  2779    19958      203      42       3        0         -1000 sshd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.656670  2789     0  2789     5622       56      17       3        0             0 xinetd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.653452  Out of memory: Kill process 43390 (mysql) score 1000 or sacrifice child
    blah
    blah
    blah
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.617265  pid    uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.622250  1828     0  1828     4331      116      14       3        0         -1000 udevd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.627310  2664     0  2664    28002       53      23       3        0         -1000 auditd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.633181  2680     0  2680    62032     1181      24       4        0             0 rsyslogd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.638888  2694     0  2694     3444       61      11       3        0             0 irqbalance
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.644912  2710    81  2710     5430       56      14       3        0             0 dbus-daemon
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.651108  2779     0  2779    19958      203      42       3        0         -1000 sshd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.656670  2789     0  2789     5622       56      17       3        0             0 xinetd
    Sep  8 11:35:15 ip-10-23-15-70 kernel: 11810061.653452  Out of memory: Kill process 43390 (mysql) score 1000 or sacrifice child
    
    我的输出如下所示:

    ==================      0MB
    Sep 8 11:35:15 pid  0MB name         <---- should be header (Pid virt rss etc)
    Sep 8 11:35:15 1828 0MB udevd
    Sep 8 11:35:15 2664 0MB auditd
    Sep 8 11:35:15 2680 4MB rsyslogd
    Sep 8 11:35:15 2694 0MB irqbalance
    Sep 8 11:35:15 2710 0MB dbus-daemon
    Sep 8 11:35:15 2779 0MB sshd
    Sep 8 11:35:15 2789 0MB xinetd
    Sep 8 11:35:15 2822 0MB crond
    Sep 8 11:35:15 Out  0MB or           <---- should be footer (out of memory etc)
    ==================      0MB 
    Sep 8 11:35:15 pid  0MB name         <---- should be header (Pid virt rss etc)
    Sep 8 11:35:15 1828 0MB udevd
    Sep 8 11:35:15 2664 0MB auditd
    Sep 8 11:35:15 2680 4MB rsyslogd
    Sep 8 11:35:15 2694 0MB irqbalance
    Sep 8 11:35:15 2710 0MB dbus-daemon
    Sep 8 11:35:15 2779 0MB sshd
    Sep 8 11:35:15 2789 0MB xinetd
    Sep 8 11:35:15 2822 0MB crond
    Sep 8 11:35:15 Out  0MB or           <---- should be footer (out of memory etc)
    ==================      0MB
    

    awk解决方案:

    $ cat tst.awk
    /swapents/ {
       x=1;
       print "=================="
       printf( "%s  %s %s   pid\t%4s\tmemused_MB\toom_score_adj\tname\n", $1, $2, $3, "rss");
       next
    }
    /Out of memory/ {
       printf( "%s  %s %s   %s\n", $1, $2, $3, substr($0,index($0,$7)));
       x=0
    }
    x {
       printf( "%s  %s %s   %s\t%4d\t%10.5f\t%13d\t%s\n", $1, $2, $3, $7, $11, ($11*4)/1024, $15, $16 )
    }
    
    您可以使用printf函数中的说明符处理格式,如第6列中的精度。请使用以下命令调用此命令:

    $ awk -f tst.awk /var/log/messages
    
    编辑:带排序

    OP要求按rss列对输出进行排序。使用标准的
    排序
    在这里不起作用,因为您希望在开始和结束匹配之间进行排序。您可以通过将中间结果保存在数组中并使用自定义函数对其进行排序来解决此问题。像这样:

    $ cat tst2.awk
    /swapents/ {
        x=1;
        print "=================="
        printf( "%s  %s %s   pid\t%4s\tmemused_MB\toom_score_adj\tname\n", $1, $2, $3, "rss");
        next
    }
    /Out of memory/ {
        n=asort(a, sorted, "cmp_rss")
        for (i=1; i<=n; i++) {
            print sorted[i]
        }
        delete a;
        printf( "%s  %s %s   %s\n", $1, $2, $3, substr($0,index($0,$7)));
        x=0
    }
    x {
        a[i++] = sprintf( "%s  %s %s   %s\t%4d\t%10.5f\t%13d\t%s", $1, $2, $3, $7, $11, ($11*4)/1024, $15, $16 );
    }
    function cmp_rss(i1, v1, i2, v2)
    {
        split(v1, a1, " ")
        split(v2, a2, " ")
        rss1=a1[5];
        rss2=a2[5];
        return (rss1 - rss2)
    } 
    

    根据Marc Lambrich的回答,我能够创建一个行程序来完成这项工作。非常感谢。现在唯一缺少的是按rss列进行排序,但我无法对rss字段进行排序

    less /var/log/messages|awk '/swapents/ {x=1; print "==================";gsub(/\[|\]/, "") ;printf "%s %s %s %s %10s %10s %10s %15s memory_used %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$16 ;next } {gsub(/\[|\]/, "")} /Out of memory/ {print $0 ;x=0 } x {printf "%s %s %s %s %10s %10s %10s %15s %9.2fMB %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$11*4/1024,$16}'
    
    为便于阅读,awk代码的格式为:

    /swapents/ {
        x=1; 
        print "==================";
        gsub(/\[|\]/, "");
        printf "%s %s %s %s %10s %10s %10s %15s memory_used %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$16 ;
        next 
    } 
    {
        gsub(/\[|\]/, "")
    } 
    /Out of memory/ {
        print $0;
        x=0 
    } 
    x {
        printf "%s %s %s %s %10s %10s %10s %15s %9.2fMB %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$11*4/1024,$16
    }
    

    嘿,很棒的解决方案。这是我用过的/swappents/{x=1;print“===================“gsub(/[|]/,”“)print$0”\t\t“$11 next}{gsub(/[|]/,”“)}/内存不足/{print$0 x=0}x{printf”%s\t\t%10.2f\n“,$0,$11*4/1024}这并不排序。有没有一种方法可以在命令行中使用它而不创建文件?我无法在我使用的计算机上创建文件。添加了rss列的排序示例。不创建文件?当然,只是
    awk-f tst2.awk input.txt
    不会为您创建文件。谢谢您的排序方法,这很酷。通过不创建文件,我的意思是我无法在运行此操作的机器上创建awk文件。看起来我可能需要从外部进行排序:(.谢谢你的帮助,现在就可以了,不用排序就可以生存。我可以想象你不被允许访问公司的生产服务器。但是,有些公司在允许读取访问的地方使用日志服务器。还有:没有义务,但是如果你真的满意的话,你可以接受答案。是的,这是真的,但是日志服务器只有e记录了2天前的日志。所以我不得不等待,因为问题现在正在发生,所以我不得不等待。在我的答案中添加了排序示例。
    less /var/log/messages|awk '/swapents/ {x=1; print "==================";gsub(/\[|\]/, "") ;printf "%s %s %s %s %10s %10s %10s %15s memory_used %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$16 ;next } {gsub(/\[|\]/, "")} /Out of memory/ {print $0 ;x=0 } x {printf "%s %s %s %s %10s %10s %10s %15s %9.2fMB %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$11*4/1024,$16}'
    
    /swapents/ {
        x=1; 
        print "==================";
        gsub(/\[|\]/, "");
        printf "%s %s %s %s %10s %10s %10s %15s memory_used %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$16 ;
        next 
    } 
    {
        gsub(/\[|\]/, "")
    } 
    /Out of memory/ {
        print $0;
        x=0 
    } 
    x {
        printf "%s %s %s %s %10s %10s %10s %15s %9.2fMB %-s\n", $1,$2,$3,$4,$7,$10,$11,$15,$11*4/1024,$16
    }