разобрать вывод iostat с помощью awk

Я пытаюсь отфильтровать вывод параметра avgserv из строки read, используя awk.

Вывод по умолчанию моей команды iostat: iostat -D hdisk0 выглядит следующим образом:

bash-4.4$ iostat -D hdisk0

System configuration: lcpu=32 drives=9 paths=126 vdisks=0

hdisk0          xfer:  %tm_act      bps      tps      bread      bwrtn
                          0.0      3.0K     0.1       98.3        2.9K
                read:      rps  avgserv  minserv  maxserv   timeouts      fails
                          0.0      0.8      0.0      0.0           0          0
               write:      wps  avgserv  minserv  maxserv   timeouts      fails
                          0.1      2.2      0.0      0.0           0          0
               queue:  avgtime  mintime  maxtime  avgwqsz    avgsqsz     sqfull
                          0.0      0.0      0.0      0.0        0.0         0.0
--------------------------------------------------------------------------------

Используя: iostat -D hdisk0 | awk '/avgserv/' Мне удалось напечатать строки, которые соответствуют: avgserv

bash-4.4$ iostat -D hdisk0 | awk '/avgserv/'
                read:      rps  avgserv  minserv  maxserv   timeouts      fails
               write:      wps  avgserv  minserv  maxserv   timeouts      fails

Но,

Во-первых, я возвращаю только заголовки без фактических значений.

Во-вторых, мне нужно вернуть параметр avgserv только для строки read. Не для строки записи.

Мой окончательный вывод должен содержать только значение параметра avgserv и только для строки read:

0.8

После некоторого копания мне удалось вернуть только параметр avgserv, используя: iostat -D hdisk0 | awk '/avgserv/ {print $3}'

Но тем не менее, я получаю требуемый параметр для обеих строк (чтение и запись) и снова без фактического значения.


person edwio    schedule 19.11.2019    source источник


Ответы (2)


Не могли бы вы попробовать следующее.

your_command | 
awk '
/avgserv/ && /read/{
  found=1
  next
}
found{
  print $2
  found=""
}'

Однослойная форма решения:

your_command | awk '/avgserv/ && /read/{found=1;next} found{print $2;found=""}'

Объяснение: добавлено пояснение к приведенному выше коду.

your_command |              ##Sending your command output as standard input to awk command.
awk '                       ##Starting awk command from here.
/avgserv/ && /read/{        ##Checking condition if a line has string avgserv AND read then do following.
  found=1                   ##Setting variable found value to 1 here.
  next                      ##next will skip all further statements from here.
}                           ##Closing BLOCK for above condition here.
found{                      ##Checking condition if found is NOT NULL then do following.
  print $2                  ##Printing 2nd field here.
  found=""                  ##Nullifying variable found here.
}'                          ##Closing BLOCK for found condition here.
person RavinderSingh13    schedule 19.11.2019
comment
не могли бы вы объяснить свой код? есть ли вариант для команды с одним вкладышем? - person edwio; 19.11.2019
comment
@edwio, объяснение уже добавлено в мое решение :) Конечно, теперь можно добавить однострочную форму. - person RavinderSingh13; 19.11.2019
comment
@edwio, я также добавил одну линейную форму решения, пожалуйста, дайте мне знать в случае каких-либо вопросов здесь. - person RavinderSingh13; 19.11.2019
comment
Зачем нам нужно использовать found= (обнуляющая переменная найдена здесь)? мы уже печатаем значение 2-го поля - person edwio; 19.11.2019
comment
@edwio, это потому, что он НЕ должен печатать что-либо (любую строку), кроме следующей строки avgserv и read, иначе, как только он будет 1 и НЕ очищен позже, он также может печатать ненужные результаты, ура. - person RavinderSingh13; 19.11.2019

Краткий снимок с противоположной стороны:

$ iostat -D hdisk0 | awk '/write: +.*avgserv/{ print v; exit }{ v=$2 }'
0.8
person RomanPerekhrest    schedule 19.11.2019
comment
не могли бы вы уточнить, что вы имели в виду под противоположным? - person edwio; 10.12.2019