Вернуть определенное совпавшее (под) значение с помощью grep в linux

362
Robin Gould

Я использую Zabbix агент (программное обеспечение для ведения журналов) в Ubuntu и хочу пропинговать внутренний IPIP / GRE-туннель, чтобы постоянно измерять качество соединения.

Теперь агент Zabbix по умолчанию не позволяет выполнять команду ping для внутреннего туннеля, но, к счастью, он позволяет создавать «пользовательские параметры», в основном он позволяет вам выполнить одну команду оболочки unix и передать данные в ваше программное обеспечение.

Для этого мне нужно выполнить команду fping / ping, которая получает одно значение для zabbix. Я хочу, чтобы это значение было числом десятичных секунд или миллисекунд задержки или 0 при отсутствии соединения в течение 1 секунды. Ниже я уже разработал команду, которая выполняет 5 пингов на IP туннеля, а затем возвращает средние значения.

(IP-адрес ниже является примером данных) это то, что я получил до сих пор:

fping -e -q -p 1000 -c 5 8.8.4.4 2> /dev/null | grep -oP '[0-9\.]+/([0-9\.]+)/[0-9\.]+$' 

Полная возвращаемая строка выглядит так:

8.8.4.4 : xmt/rcv/%loss = 5/5/0%, min/avg/max = 2.78/2.94/3.19" 

Теперь результат grep такой:

2.78/2.94/3.19 

Я хочу последовательно получить второе значение (2.94 выше), поэтому мой вопрос заключается в том, какой самый эффективный способ сделать это в одной команде?

0

2 ответа на вопрос

1
AFH

Я бы использовал sedвместо grep, так что ваш фильтр становится:

... | sed -n 's%^.* = .* = .*/\(.*\)/.*%\1%pg' 

Заметки:-

  • Поскольку мы сопоставляем /символ, я заменил обычный разделитель строк, %чтобы упростить выражение, избегая необходимости экранировать /.
  • Мы соответствие всей линии и заменить его, что происходит между двумя косыми чертами после два знака равенства, разделённого \(и \)в строке матча и \1в замене.
  • Мы ничего не выводим ( -n) за исключением строк, где есть match ( %pg).

Чтобы упростить мою иллюстрацию, я использовал .*цифры. Вы можете использовать [0-9\.]+, но вам нужно будет использовать расширенный RE сgrep -rn ...

Если вы еще не использовали sed, я рекомендую этот учебник .

Спасибо за ваш ответ, однако, если я выполню следующую команду, я получу пустой результат: fping -e -q -p 1000 -c 5 8.8.4.4 | sed -n 's% ^. * =. * =. * / \ (. * \) /.*% \ 1% pg' Однако, если я запускаю команду вручную, то копирую результат в эхо, он работает, Что я делаю неправильно ? Robin Gould 8 лет назад 0
очевидно, что fping всегда выводит в stderr вместо stdin, я решил это, добавив 2> & 1 в конце команды fping Robin Gould 8 лет назад 0
В `bash` вы можете сократить перенаправление на` fping ... | & sed ... `. AFH 8 лет назад 0
0
Richlv

Почему нет cut -d/ -f8? Как в:

echo '8.8.4.4 : xmt/rcv/%loss = 5/5/0%, min/avg/max = 2.78/2.94/3.19"' | cut -d/ -f8 
Это также сработало, хотя решение sed кажется более гибким :) В любом случае, спасибо! Robin Gould 8 лет назад 0
Это хорошее решение, если в выводе из `fping` нет дополнительных строк в разных форматах: каждая дополнительная строка во входных данных для` cut` будет давать пустую строку в выходных данных. Чтобы устранить их, вам нужен дополнительный фильтр `... | grep -v '^ $' `. AFH 8 лет назад 0
Конечно, `sed` или` awk` сработали бы - я попытался дать самый простой ответ на поставленную задачу :) Richlv 8 лет назад 0

Похожие вопросы