Как фильтровать абзацы


ramok аватар

ramok - Posted on 16 Январь 2009

Иногда возникает необходимость отфильтровать только те абзацы в тексте, которые содержат какое либо слово или строку.
Под абзацами подразумевается текст отделенный от остального текста пустой строкой.

Практический пример:
при настройке мультимедийных клавиш, 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

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)

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

Отправить комментарий

Google Friend Connect (leave a quick comment)
loading...
Содержание этого поля является приватным и не предназначено к показу.