Это может работать для вас (GNU sed):
sed -n '/\S/{h;:a;n;//{H;$!ba};g;/5555/p}' file
Отключить неявную печать -n
.
Начать набор строк в области удержания, когда текущая строка содержит непробельный символ.
Завершить коллекцию пустой строкой или концом файла.
Проверить коллекцию на наличие требуемой строки и, если она совпадает, напечатать всю коллекцию. Повторите.
Чтобы добавить новую строку к результату, используйте:
sed -n '/\S/{h;:a;n;//{H;$!ba};z;H;g;/5555/p}' file
Sed - редактор потоков. Он используется для редактирования текстовых файлов и обычно обрабатывает строку текста одновременно. У него есть два буфера, которые он использует для выполнения sh этой задачи. Пространство шаблона (PS) и резервный буфер, называемый пространством удержания (HS). Обычный поток событий заключается в том, что sed читает строку текста в PS и удаляет ее новую строку. Инструкции (команды) Sed действуют на PS, лишенный символ новой строки повторно добавляется, и результат доставляется на стандартный вывод, т.е. печатается.
Опция -n
отключает имплицитный характер доставки PS на стандартный вывод. т. е. если вы хотите что-то напечатать, вы должны выполнить для этого команду, такую как p
или P
, которая печатает PS или печатает первую строку PS.
Sed использует regexp для принятия решения если применять команды к PS. /\S/
- это регулярное выражение, которое проверяет PS на наличие любого непробельного символа. Sed использует парены для группировки команд, а команды разделяются точками с запятой.
Команда h
заменяет все, что было в области удержания (HS), содержимым PS.
Sed может выполнять петли. Это делается путем определения метки-заполнителя для l oop и команды для перехода к метке-заполнителю l oop. :a
определяет все oop местозаполнитель с именем a
, а b
- команда прерывания.
Команда n
извлекает следующую строку в PS. Обычно это приводит к тому, что содержимое PS передается на стандартный вывод перед его заменой, но поскольку опция -n
включена, ее содержимое просто выбрасывается.
Сокращение //
для предыдущее регулярное выражение, т. е. содержимое PS теперь снова проверяется на наличие непробельного символа, и если это так, то выполняются команды внутри паренов. В этом случае H
добавляет PS к HS, отделенному его новой строкой, которая была предварительно удалена.
Sed знает номер строки каждой строки, а также знает, когда в PS присутствует последняя строка файла. $
обозначает последнюю строку. !
является командой not и отменяет предыдущий адрес или регулярное выражение, например, $!
означает не последнюю строку файла. Сложить все вместе $!ba
означает, что если это не последняя строка файла, разбить b
на заполнитель a
. Таким образом, поток команд направляется обратно к :a
и sed возобновляет обработку с этого места.
Если //
не совпадает, это подразумевает две возможности: либо текущая строка пуста, либо это последняя строка файла. z
убирает PS и очищает его. H
добавляет пустую строку к HS, разделенную новой строкой.
g
заменяет PS содержимым HS. Коллекция строк, которые построил l oop, теперь находится в PS. Другое регулярное выражение пытается сопоставить PS /5555/
и, если это так, выдает команду p
, которая печатает PS.
Таким образом, программа sed перемещается по файлу, собирая коллекции непустых строк в HS и печатая их, если соответствует регулярное выражение.