現在のデータ:
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 には複数の値があります。
私がしたいことは2つの部分です。
すべての値を加算できます。特定モードデータファイルのすべての行で。たとえば、データファイルのすべての行の「on__host」の合計値を知りたい場合です。
ログのすべての行にわたって行ごとにすべてのパターンのすべての値を合計する機能。
私は9番目のフィールドに1つの値しかない古いデータで作業しています。これは扱いやすいです。データは次のとおりです。
前のデータ
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システムで実行されることが予想されます。私が使用するシェルは/bin/shまたは/bin/bashです。
要求の最初の部分でデータファイルのすべての行にあるすべてのパターンのすべての値を追加した場合、出力は数値の合計になるはずです。これは504(私が選択したランダム数)です。 )。
私の要求の2番目の部分で特定のパターンの値を追加した場合、出力はその特定のパターンの値の合計でなければなりません。つまり、「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]]
}'
しかし、読むのはそれほど簡単ではありません。
2番目の質問の場合、これは最も短いまたは最も効率的な方法ではありませんが、合計を計算できると思います。
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