awk on vmstat para obter si, então

3

Estou escrevendo um script de shell para verificar os dados vmstat si e so em vários intervalos de tempo

vmstat 1 de saída de amostra:

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

Eu quero usar o awk, sed para extrair si e so em diferentes variáveis para uso posterior. Eu sou novo para awk, sed e ainda estou lutando para encontrar o meu caminho. Você pode me mostrar como posso fazer isso?

    
por APZ 05.11.2011 / 01:08

3 respostas

1

Este script AWK lê a segunda linha e usa os cabeçalhos de campo como índices nos dados de cada linha para que você possa se referir a eles pelo nome. Aqui está o one-liner. Eu quebro linha por linha abaixo.

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)}'

Como mostrado, ele imprime o conteúdo da coluna "si" e a média no final. Você pode manipular vários campos ou fazer uma iteração em todos os campos.

Você pode expandir isso para manipular outros campos, fazer comparações de uma linha com a anterior ou fazer totais ou outros cálculos. Você pode parar, como mostrei, depois de um certo número de registros.

A opção -n para vmstat faz com que o cabeçalho seja impresso apenas uma vez.

A divisão:

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)}'
    
por 06.11.2011 / 13:44
1
SWAPIN=$(vmstat | egrep -v 'swap|si' | awk '{ print $7 }')
SWAPOUT=$(vmstat | egrep -v 'swap|si' | awk '{ print $8 }')

ou mais "padrão":

$ vmstat | awk '{ for (i=1; i<=NF; i++) if ($i=="si") { getline; print $i }}'
  • A variável NF incorporada fornece o número de campos no linha atual
  • getline lê a próxima linha de entrada
por 05.11.2011 / 02:15
0

Eu me sentiria negligente se não fornecesse os equivalentes em perl:

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

Tags