Как фильтровать абзацы
Иногда возникает необходимость отфильтровать только те абзацы в тексте, которые содержат какое либо слово или строку.
Под абзацами подразумевается текст отделенный от остального текста пустой строкой.
Практический пример:
при настройке мультимедийных клавиш, xev выводит очень быстро, очень много текста. Хочется фильтровать только описание событий связанных с определенными клавишами. Например пусть это будет XF86Forward и XF86Back.
Собственно пример команды
$ xev | sed -ne 'H;$bz;/^$/{:z;g;/XF86Forward\|XF86Back/p;s/.*//;x}'Запускаем это и нажимаем все мультимедийные клавиши в поисках нужных.
Как это работает:
1. Накапливаем в буфере (hold space) абзац
2. Если находим признак окончания абзаца (в нашем случае - пустая строка) или это последняя строка, забираем из буфера накопленный.
2.1 Проверяем если нужные слова в абзаце. Если есть - печатаем абзац.
2.2. Стираем обработаный абзац.
H; # добавляем текущую строку в hold space
$bz; # если это последняя строка, то прыгаем на обработку накопленного абзаца
/^$/{ # /^$/ находит пустую строку. Это признак того что абзац закончился.
:z; # метка начала обработки абзаца
g; # забираем из hold space абзац
/XF86Forward\|XF86Back/p; # ищем искомое, и если находим - то печатаем. Сюда можно вставить любой регесп
s/.*//; # стираем текущую строку
x # очищаем hold space
};Советы в тему по обработке блоков текста:
Удобная многострочная подсведка поиска в vim
Сворачивание в vim
- 824 просмотра
Страница для печати


Эту можно без {} вот так, (по крайне мере я так делаю :) )
xev | sed -ne 'H;$bz;/^$/!b;:z;g;/XF86Forward\|XF86Back/p;s/.*//;x'
Отправить комментарий