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

У меня есть файл 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 лучше подходят для задачи)

  • Заменить строку M в файле1 на строку N в файле2
  • Извлечение информации через awk и sed
  • Удаление последнего символа одним словом, но только если символ присутствует - в bash
  • Прочитайте столбец из файла и добавьте конкретный столбец другого файла
  • sed соответствует только во второй строке
  • Используйте sed, чтобы удалить все, кроме определенного шаблона
  • Sed: удалить между первыми n строками те, у которых заданная строка в них
  • linux + ssh + выполняет две задачи в одном ssh и печатает в CSV
  • 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

    Предоставляет ли fail2ban дополнительную защиту SSH, если пароль уже отключен?

    Как перенести установку Linux с жесткого диска на SSD?

    Как оштрафовать файл в n-out-of-m redundancy (код стирания, например, вид соломона)?

    Загрузите Linux из Linux на встроенную плату

    Как назвать объем в Linux, чтобы я мог распознавать каждый том в файловой системе?

    Что внезапно убило главный процесс?

    Удалить символ ^ M из файлов журнала

    libvirtd не приостанавливает гостей

    При загрузке tmux по умолчанию при запуске zsh-терминала

    В чем разница между запуском исполняемого файла только по имени и добавлением точки / косой черты перед ним?

    терминал: отображение специальных символов

    Почему двоичные файлы apache, построенные с 64-битными gcc, смешиваются с 32 и 64 битами?

    Настройка sendmail как реле для интернет-провайдера

    Procmail распознает электронные письма, которые уже были скопированы в папку

    Вопрос о виртуализации CentOS и KVM и PCI Passthrough

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