Регулярное выражение POSIX ERE с использованием хвостового плагина в collectd

Я пытаюсь сопоставить определенные значения в файле, используя плагин «хвост» для collectd. Этот плагин поддерживает только синтаксис POSIX ERE. Пример файла ниже:

capture.kernel_packets                     | Total                     | 25496291490
capture.kernel_drops                       | Total                     | 873229305

Попытка №1:

capture\.kernel_packets.*Total.*\|\s+(\d+)

Я хочу извлечь значение «25496291490» в первой группе захвата.

Попытка №2:

capture\.kernel_packets.*Total.*\|\s+(\d+)\1

Кажется, он захватывает только полное совпадение. Следующее работает, но не поддерживается POSIX ERE:

capture\.kernel_packets.*Total.*\|\s+\K\S+

https://collectd.org/documentation/manpages/collectd.conf.5.shtml#plugin_tail http://www.boost.org/doc/libs/1_44_0/libs/regex/doc/html/boost_regex/syntax/basic_extended.html

Что я упускаю из виду? Спасибо!


person Scuba_Steve    schedule 04.01.2018    source источник
comment
Просто удалите \1 из своего первого шаблона.   -  person ctwheels    schedule 04.01.2018
comment
@ctwheels Я получаю следующую ошибку: collectd[11093]: utils_match: match_apply: callback failed, предположительно потому, что ожидается число, а не вся строка. Согласно документации, первое подвыражение должно соответствовать чему-то, что может быть преобразовано в число с помощью strtoll(3) или strtod(3)   -  person Scuba_Steve    schedule 04.01.2018


Ответы (1)


Я думаю, что ваша первая попытка близка.

Я подозреваю, что вы можете упустить из виду необходимость дважды экранировать строку для использования в collectd/tail. Позволь мне объяснить.

Во-первых, код collectd компилирует строку регулярного выражения, которую вы предоставляете с флагами.

REG_EXTENDED | REG_NEWLINE

Кроме того, строка, которую вы указываете в файле tail.conf в поле Regex, не является фактическим регулярным выражением. Эта строка подходит для использования в языке C, поэтому вы должны знать о двух отдельных уровнях экранирования.

1) экранирование, требуемое синтаксисом расширенного регулярного выражения, например. если вы хотите использовать один из этих

.[{}()\*+?|^$ 

тогда вам нужно избежать его с помощью \

Так, например, если вы хотите использовать фактический символ «*», тогда регулярное выражение требует, чтобы у вас было «\*», чтобы компилятор знал, что вы имеете в виду «звездочку», а не «регулярное выражение с нулевым или более повторением».

2) Но также вам нужно экранирование, требуемое языком C.

Таким образом, чтобы создать фактический символ «|» в строке регулярного выражения, вам нужно экранировать его, как этот «\|». И чтобы предоставить эту строку регулярного выражения в файле tail.conf в виде строки C, вам нужно снова экранировать ее '\\|'.

Итак, вам нужна эта строка регулярного выражения:

capture\.kernel_packets.*Total.*\|\s+([0-9]+)

Который вы бы предоставили в своем tail.conf с дополнительным экранированием C как:

capture\\.kernel_packets.*Total.*\\|\\s+([0-9]+)

Сопоставляется вся строка, и нужное число оказывается в группе 1, что дает collectd число, необходимое для синтаксического анализа.

person Rachel    schedule 10.07.2018