Замена совпадающего текста после двух совпадающих строк

У меня есть файл YAML, который включает в себя строфу, это выглядит так:

admin::common::passwords: alice: password: '$6$oTQhLvN/4VFJPscD$8LYwUMSFi' bob: password: '$6$JKOtLF0wHeZfIskt$W/M5.ugDS' 

Если переменная оболочки $ ACCOUNT содержит имя учетной записи (alice, bob и т. Д.), А $ YAML – это имя файла YAML, я могу добавить новую запись с sed, как это. Он вставляет новую учетную запись непосредственно в строку «admin :: common :: пароли:», поэтому я знаю, что она находится в правильной строфе:

  sed -i /'^admin::common::passwords:'/a"\ ${ACCOUNT}:\n password: '${ENCRYPTED_PASS}'" $YAML 

Я могу найти существующую учетную запись, подобную этой, с awk. Опять же, это находит строфу, затем находит учетную запись внутри этой строфы (возможно, это возможно сделать все в awk, но я недостаточно хорош для awk, и это выполнит эту работу):

  awk "BEGIN{RS=ORS="\n\n";FS=OFS="\n"}/admin::common::passwords:/" $YAML | grep -A1 "^[ ]*${ACCOUNT}:" 

Но чтобы удалить строку, лучшее, что я могу придумать, это следующее:

 sed -i "/^ ${ACCOUNT}:/,+1d" $YAML 

Которая удалит любую строку «^ alice:» в любом месте файла, независимо от того, находится ли она в строфе admin :: common :: passwords или в другом месте.

Я не могу делать никаких предположений о содержимом файла, за исключением того, что он содержит ровно одну строчку admin :: common: пароли (если это не так, то она была бы создана другой частью моего скрипта; этот бит легко).

Итак, мой вопрос заключается в следующем: как я могу улучшить этот sed, чтобы сказать « Искать» ^ $ {ACCOUNT}: « в строге admin :: common :: паролей и удалить соответствующую строку, а также строку под ней », ?

(это, конечно, не обязательно, может быть, что awk или даже Perl лучше подходят для задачи)

  • Вывести некоторые разделы текстового файла
  • Прерывает ли sed поврежденный целевой файл?
  • Извлечение справочного сообщения из самого скрипта
  • Простое использование суффикса адресной строки '/ M'?
  • sed не удаляет символ новой строки
  • Обратное совпадение в sed, замените противоположное тому, что было найдено
  • Извлечение нескольких экземпляров текста между теми же двумя строками текста
  • Проблема с вставкой новой строки между странными html-символами в html-файле - UTF-8
  • 2 Solutions collect form web for “Замена совпадающего текста после двух совпадающих строк”

     sed " /^admin::common::passwords:$/,/^[^ ].*:$/ { /^ $ACCOUNT:$/ { N;d } }" < "$YAML" 

    То есть, приложите свою строфу к строфе в разделе, совпадающем между admin::common... и следующим whatever-section:

    Остерегайтесь, что . характер, общий для имен пользователей, также является оператором регулярных выражений, поэтому john.doe будет соответствовать john.doe но, например, johnWdoe .

    Обратите внимание, что вышеуказанное не будет работать, если у вас есть два последовательных раздела admin::common::passwords а удаляемая учетная запись – во второй.

    Если, как указывает Otheus , секции работают до следующей строки с одинаковым или меньшим количеством символов пробела, а ваш раздел admin::common::passwords: могут иметь некоторые ведущие пробелы, то, вероятно, настало время перейти на другой язык, например awk :

     awk -v account="$ACCOUNT" ' match($0, /[^ ]/) && RSTART <= n {n = 0} n && NF == 1 && $1 == account ":" {getline; next} !n && /^ *admin::common::passwords:$/ { match($0, /[^ ]/) n = RSTART } {print}' < "$YAML" 

    Было бы гораздо безопаснее использовать предварительно построенные библиотеки для синтаксического анализа всего файла (например, https://stackoverflow.com/questions/1773805/how-can-i-parse-a-yaml-file ), чтобы ваш изменения, а затем повторно сохранить измененный файл. Выполнение нескольких слепых изменений текста в структурированном текстовом файле, как это, просто требует, чтобы что-то пошло не так.

    Interesting Posts

    Нажмите любую клавишу для приостановки сценария оболочки, нажмите еще раз, чтобы возобновить

    Использование systemd для выполнения сценария перед отключением системы?

    Использование ЦП операций файловой системы, не показанных сверху

    Ошибка скрипта Bash со строками с путями с пробелами и подстановочными знаками

    Что делает «while test $ # -gt 0»?

    Стандарты и протоколы, которые были впервые реализованы в Linux / Open source

    Linux Mint – не обнаружение монитора, подключенного через концентратор USB-C к HDMI

    процесс не использует новую конфигурацию открытого файла, которую я установил?

    конвертировать * .po файл в * .pot

    Настройка цифрового пианино и компьютера с MIDI-интерфейсом

    Как распечатать конкатенированную дату и время в секундах

    Sed: как заменить 0 и:?

    awk: печатать строки после матча до конца файла

    Дисковый раздел при двойной загрузке Ubuntu 14.04 на Windows 10

    Почему `minicom` присоединяет символ` 0xOD` к серийному текстовому сообщению?

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