awk上vmstat得到si,所以

我正在编写一个shell脚本,以不同的时间间隔检查vmstat si等数据

vmstat 1样本输出:

 procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- rb swpd free buff cache si so bi bo in cs us sy id wa 0 0 45820 899252 86700 468520 0 0 0 60 127 5821 20 7 34 0 0 0 45820 899252 86704 468504 0 0 0 32 44 104 0 0 100 0 

我想用awk,sed来提取si soso进一步使用。 我对awk很陌生,sed还在努力寻找自己的路。 你能告诉我怎么做到这一点?

这个AWK脚本读取第二行,并使用字段标题作为索引到每行的数据中,以便您可以通过名称引用它们。 这是一行。 我在下面逐行分解。

 vmstat -n 1 | awk 'NR == 1 {next} NR == 2 {for (i = 1; i <= NF; i++) fields[$i] = i; next} {split($0, data); item = data[fields["si"]]; print item; totals[fields["si"]] += item} NR >= 6 + 2 {exit} END {print "Average", totals[fields["si"]]/(NR - 2)}' 

如图所示,它打印“si”列的内容和最后的平均值。 您可以处理多个字段或迭代所有字段。

你可以扩展这个来处理其他领域,比较一行到前一行或做总计或其他计算。 正如我所显示的那样,您可以在一定数量的logging之后停下来。

vmstat-n选项导致标题仅被打印一次。

细目:

 vmstat -n 1 | awk 'NR == 1 {next} # skip the first line # for the second line, create an array of field positions indexed by the # name of the field then do "next" so this line is not processed further NR == 2 {for (i = 1; i <= NF; i++) fields[$i] = i; next} {split($0, data); # split the line of values into an array item = data[fields["si"]]; # pick out an item based on its name print item; totals[fields["si"]] += item} # accumulate a total # exit when the number of desired records (plus the two header lines) # has been read, you could use a vmstat argument to do this instead NR >= 10 + 2 {exit} # calculate and print the average (subtract the two header lines from the record count) END {print "Average", totals[fields["si"]]/(NR - 2)}' 
 SWAPIN=$(vmstat | egrep -v 'swap|si' | awk '{ print $7 }') SWAPOUT=$(vmstat | egrep -v 'swap|si' | awk '{ print $8 }') 

或更“标准”的方式:

 $ vmstat | awk '{ for (i=1; i<=NF; i++) if ($i=="si") { getline; print $i }}' 
  • 内置的NFvariables为您提供了当前行中的字段数量
  • getline读取下一个input行

如果我没有提供perl的等价物,我会感到失望:

 SWAPIN=$(vmstat | perl -lane 'next if /^(procs|r)/; print $F[7]') SWAPOUT=$(vmstat | perl -lane 'next if /^(procs|r)/; print $F[8]')