awk 在行字段中添加数字的方法

awk 在行字段中添加数字的方法

现在数据:

blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,on__host=92 SERVICE__ALERT_=51 Warning___The__results__of__service=16 Warning___on__host=92 Auto_save__of__retention__data__completed=1 Warning___Return=68 PASSIVE__SERVICE__CHECK_=53 ,1026--1313,1
blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,on__host=14 SERVICE__ALERT_=51 Warning___The__results__of__service=16 Warning___on__host=93 Auto_save__of__retention__data__completed=1 Warning___Return=68 PASSIVE__SERVICE__CHECK_=53 ,1026--1313,1
blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,on__host=93 SERVICE__ALERT_=51 Warning___The__results__of__service=16 Warning___on__host=92 Auto_save__of__retention__data__completed=1 Warning___Return=8 PASSIVE__SERVICE__CHECK_=53 ,1026--1313,1
blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,on__host=73 SERVICE__ALERT_=51 Warning___The__results__of__service=16 Warning___on__host=99 Auto_save__of__retention__data__completed=1 Warning___Return=68 PASSIVE__SERVICE__CHECK_=53 ,1026--1313,1
blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,on__host=93 SERVICE__ALERT_=51 Warning___The__results__of__service=16 Warning___on__host=75 Auto_save__of__retention__data__completed=1 Warning___Return=38 PASSIVE__SERVICE__CHECK_=53 ,1026--1313,1
blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,on__host=21 SERVICE__ALERT_=51 Warning___The__results__of__service=16 Warning___on__host=12 Auto_save__of__retention__data__completed=1 Warning___Return=28 PASSIVE__SERVICE__CHECK_=23 ,1026--1313,1[/CODE]

上面每一行中的字段均以“逗号”分隔。我感兴趣的是字段 9。

字段 9 有多个值。

我想做的是两部分:

  1. 能够将a的所有值相加具体模式在数据文件的所有行中。例如,如果我想知道数据文件中所有行的“on__host”总值。

  2. 能够将日志中所有行的每行所有模式的所有值相加。

我正在使用一个旧数据,该数据在第 9 个字段中只有一个值。这很容易处理。数据如下:

上一个数据

blah1,dah,blaha,sweet,games.log,5297484456,nagios-toin,529748456,53,1026--1313,1

我需要做的就是将所有行的第 9 个字段中的值相加:

awk -F, 'BEGIN{sum=0} {sum+=$9} END {print sum}' data.prev

可以为我解决这个问题的脚本如下所示:

#!/bin/sh
Pattern=$1
if [ "${Pattern}" = "allpatterns" ] ; then
   awk should add up all the values in the 9th field of data in data.now
else
   if the user did not specify "allpatterns", then, awk should take the pattern name specified by the user and use that to decide which pattern to add up in the 9th field of all the lines.
    awk -F"," '$9 ~ /'${Pattern}'/ '{do awk magic}'  -- this is just an idea.
fi

该脚本预计可以在所有 UNIX 系统上运行。我将使用的 shell 是 /bin/sh 或 /bin/bash。

对于我的请求的第一部分,如果将​​数据文件中所有行上的所有模式的所有值相加,则输出应该只是数字的总和..即 504 (只是我选择的任意数字)。

对于我的请求的第二部分,如果将​​特定模式的值相加,则输出应该只是该特定模式的值的总和......即“on__host=400”。

答案1

这是一种更容易完成的事情perl(并不是说有很多事情awk比更容易完成perl):

$ perl -F, -lae '$c{$1} += $2 while $F[8] =~ /(\S+)=(\d+)/g;
                 END {print "$_ => $c{$_}" for sort keys %c}' < file
Auto_save__of__retention__data__completed => 6
PASSIVE__SERVICE__CHECK_ => 288
SERVICE__ALERT_ => 306
Warning___Return => 278
Warning___The__results__of__service => 96
Warning___on__host => 463
on__host => 386

例如,如果您只需要该值,请将块更改END为。{print $c{on__host}}on__host

答案2

对于第一部分,我认为这样的事情会起作用:

cat data.now | awk -F, '{print $9}' | sed 's/=/ /g' | awk '
    { 
        for (i = 1; i <= NF; i += 2) {
            a[$i]+=$(i+1); 
        }
    } 
    END {
        for (i in a) print i, "=", a[i]
    }'

此代码产生以下输出:

PASSIVE__SERVICE__CHECK_ = 288
Warning___Return = 278
Auto_save__of__retention__data__completed = 6
SERVICE__ALERT_ = 306
Warning___The__results__of__service = 96
on__host = 386
Warning___on__host = 463

这里唯一的潜在问题是顺序与原始文件的顺序不同。如果订单对您很重要,您可以使用:

cat data.now | awk -F, '{print $9}' | sed 's/=/ /g' | awk '
    { 
        for (i = 1; i <= NF; i += 2) {
            a[$i]+=$(i+1); 
            b[i]=$i;
        }
    } 
    END {
        for (i in b) print b[i], "=", a[b[i]]
    }'

但它并不那么容易阅读。

对于你的第二个问题,我认为这可以计算总和,尽管它可能不是最短或最有效的方法。

cat data.now | awk -F, '{print $9}' | 
    sed "s/.*\<${Pattern}=\([0-9]\+\).*/\1/g" | 
    awk '{s += $1} END {print s}'

答案3

您可以在空间上split归档$9,然后迭代结果以选择模式,然后split找到找到的元素=以提取值:

awk -F, -v pat='^on__host=' '{
  n = split($9,a," "); 
  for(i=1;i<=n;i++) {
    if(a[i] ~ pat) {
      split(a[i],b,"="); 
      sum+=b[2]
    } 
  }
} 
END{print sum}
' data.now 

相关内容