This AWK script reads the second line and uses the field headers as indices into the data on each line so you can refer to them by name. Here is the one-liner. I break it out line by line below.
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)}'
As shown, it prints the contents of the "si" column and the average at the end. You could handle multiple fields or iterate over all the fields.
You can expand on this to handle other fields, do comparisons of one line to the previous one or do totals or other calculations. You can stop, as I have shown, after a certain number of records.
The -n
option to vmstat
causes the header to only be printed once.
The breakdown:
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)}'