web-dev-qa-db-ja.com

vmstatでawkを実行してsiを取得します。

さまざまな時間間隔でvmstat siおよびsoデータをチェックするシェルスクリプトを書いています

vmstat 1サンプル出力:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r  b   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を使用して、sisoを異なる変数に抽出してさらに使用したいと思います。私はawk、sedに不慣れで、まだ自分の道を見つけるのに苦労しています。どうすればこれができるか教えていただけますか?

4
APZ

このAWKスクリプトは、2行目を読み取り、フィールドヘッダーを各行のデータへのインデックスとして使用するため、名前で参照できます。これがワンライナーです。以下の行ごとに分割します。

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」列の内容と最後の平均を出力します。複数のフィールドを処理することも、すべてのフィールドを反復処理することもできます。

これを拡張して、他のフィールドを処理したり、1行を前の行と比較したり、合計やその他の計算を行ったりすることができます。私が示したように、特定の数のレコードの後で停止できます。

-nオプションをvmstatにすると、ヘッダーは1回だけ印刷されます。

内訳:

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 }}'
  • 組み込みのNF変数は、現在の行のフィールド数を示します
  • getlineは次の入力行を読み取ります
1
quanta

Perlのonelinerに相当するものを提供しなかった場合、私は失望を感じるでしょう。

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