/proc/kmsg
не может использоваться другими читателями журнала, и если есть несколько читателей, только один из них получит любое заданное сообщение журнала. /dev/kmsg
совместно используется несколькими считывателями журналов, предоставляя каждому считывателю весь поток (журналов, пропущенный медленными считывателями ).
Обычные регулярные выражения не могут этого сделать; язык, который требует сбалансированных скобок, не является регулярным языком в формальном смысле. Итак, вы не можете сделать это правильно с sed
. К счастью, такие вещи, как Perl, предоставляют регулярные выражения, которые на самом деле не ограничиваются только обычными языками.
. эта мерзость (адаптирована из ответа на SO к Регулярное выражение для соответствия сбалансированным скобкам)кажется, соответствует тому, что вы хотите:
perl -0 -lne 'print "$2\n\n" while m/ \\q\{aaa\} ( \{ ( (?: [^}{]+ | (?1))*+ ) \} )/gx '
Со входом \q{aaa}{blablabla \label{BBB}} \foo{bar}{not this} \q{aaa}{bleh}
, который дает выход
blablabla \label{BBB}
bleh
т. е. с совпадающими частями, напечатанными с двумя символами новой строки между ними. С -0
, как указано выше, он также должен работать с многострочными тегами. Вы также можете изменить print $2
на print $&
, чтобы получить полный тег \q{aaa}{...}
.
Что это в основном делает, так это то, что начало \\q\{aaa\}
соответствует постоянной части тега, а внутренняя часть (?: [^}{]+ | (?1))*+
соответствует любому количеству вещей, которые являются либо строкой без фигурных скобок, либо чем-то, что может быть сопоставлено путем рекурсии в первой группе захвата (набора скобок ), т.е. совпадающей пары фигурных скобок с чем-то внутри.
.../ \\q\{aaa\} ( \{ ( (?: [^}{]+ | (?1))*+ ) \} )/ '
^1 ^2 | ^2 ^1
| | |
+---------------------+----------+
recurse to group 1
Вторая группа захвата предназначена для захвата той части, которая выводится.