Добавить текст между несколькими строками с sed, если предыдущая строка не соответствует шаблону

Я пытаюсь добавить теги <dl> вокруг списка определений с помощью sed, и, возможно, есть более простой способ сделать это (я хотел бы узнать).

Я хотел бы искать файл для любых строк, содержащих <dt> , но только в том случае, если предыдущая строка не содержит <dt> или <dd> . Когда совпадение найдено, вставьте <dl> .

Моя попытка до сих пор (что совсем не совпадает):

 sed '/^((?!<dt>).)*$/ { N /<dt>/ { s/<dt>/<dl><dt>/ } }' file 

И файл

 # TODO # * Set up mail transfer agent * Reconfigure timezone ```bash dpkg-reconfigure tzdata ``` # Hardware # <dt>RAM</dt> <dd>2GB</dd> # Partitions # <dt>`/dev/sda1`</dt> <dd>/boot</dd> <dt>`/dev/sda2`</dt> <dd>/</dd> 

Цель всего этого – написать парсер, который преобразует разметку wiki moinmoin в markdown, для переноса на новый движок вики. Список исправлений в настоящее время выполняется со следующим правилом:

 sed -i 's/^ \(.*\):: \(.*\)$/ <dt>\1<\/dt>\n <dd>\2<\/dd>/' file 

Я хотел бы, чтобы результат выглядел так:

 # TODO # * Set up mail transfer agent * Reconfigure timezone ```bash dpkg-reconfigure tzdata ``` # Hardware # <dl> <dt>RAM</dt> <dd>2GB</dd> </dl> # Partitions # <dl> <dt>`/dev/sda1`</dt> <dd>/boot</dd> <dt>`/dev/sda2`</dt> <dd>/</dd> </dl> 

Обратите внимание, что я хотел бы как можно больше использовать html. Для каждого открывающего тега должен быть закрывающий тег.

One Solution collect form web for “Добавить текст между несколькими строками с sed, если предыдущая строка не соответствует шаблону”

Это может быть больше, чем вы ожидаете, но я думаю, что это лучший способ выполнить то, что вы хотите с sed .

Этот скрипт:

  • Вставляет строку <dl> перед каждой строкой, содержащей <dt> , если перед этой строкой не было других <dt> , <dd> или <dl> .

  • Добавляет строку </dl> после каждой строки, содержащей <dd> , если строка после строки, содержащей <dd> , не содержит <dd> .

Этот скрипт sed использует пространство hold sed чтобы запомнить предыдущую строку, чтобы его можно было проверить для тегов <d[tdl]> прежде чем вставлять <dl> . Он также использует относительную адресацию ADDR,+N чтобы добавить тэг закрытия </dl> . Для определения того, находится ли <dd> в последней строке файла и требуется прилагаемый </dl> требуется специальный случай. Тестирование ( t и T ) и ветвление ( b ) широко используются для реализации логики.

 #!/bin/sh sed ' /<dt>/ { x # exchange pattern and hold space s/<d[tdl]>// # subsitutue, just testing for pattern g # copy hold space back, overwriting pattern space t end # branch to :end if previous subsitution successful i \ <dl> } $ { /<dd>/ ! b end # if <dd> on last line, append </dl> a \ </dl> } /<dd>/,+1 { # on each line containing <dd> and the line after /<dd>/ b end # if does not contain <dd>, insert </dl> i \ </dl> } :end h # copy pattern space to hold space for next round ' "$@" 

Этот скрипт изменяет образцы данных таким образом:

 [...] # Hardware # <dl> <dt>RAM</dt> <dd>2GB</dd> </dl> # Partitions # <dl> <dt>`/dev/sda1`</dt> <dd>/boot</dd> <dt>`/dev/sda2`</dt> <dd>/</dd> </dl> 
  • Использование sed в сценарии оболочки с многострочными переменными
  • использование awk для распаковки файлов в каталоге
  • Найти второе появление строки из конца файла
  • Печать значения столбца в следующей строке
  • Замените одну строку на STDIN в Makefile
  • sed не различает полное совпадение регулярных выражений и отсутствие соответствия
  • Имена файлов каталогов с sed с пробелами
  • рассчитать числа на конец и слить в одну строку
  • Преобразование содержимого файла в нижний регистр
  • Отображение файла в другом файле
  • Использовать sed для печати с первой строки до строки, содержащей последнее вхождение шаблона?
  • Grep / awk / sed для строк, состоящих только из двух букв, и строк, начинающихся с буквы и встречающих определенную длину
  • Interesting Posts

    Контролируйте точность процентного соотношения CPU или MEM в верхней части?

    добавление пути к файлу в файлы

    Предотвратить удаление пользователем файла

    удаление clamav с базой данных очистки

    nginx обратный прокси для jenkins, возвращающий 404

    mount -a блокирует мой скрипт, если какой-либо из многих удаленных дисков отключен

    Возможно ли написать портативные служебные скрипты для управления демоном?

    mmc0: ошибка -110 при инициализации SD-карты

    Необходимо получить разницу между двумя моментами в секундах

    установка mmcblk0p1 не удалась с неправильным аргументом

    Получить список разделенных запятыми списков объектов в каталоге?

    Синтаксис регулярного выражения Awk с числом повторений – различная обработка между gawk 3 и gawk 4

    В чем разница между

    Загрузочный раздел на CentOS 6

    как использовать SED для замещения комментариев в разделе комментариев

    Linux и Unix - лучшая ОС в мире.