как добавить строку, только если строка не установлена ​​после определенного слова

TigerVNC также может быть вариантом. Я считаю, что сервер работает быстрее, а клиент прост, но соответствует большинству требований.

0
16.03.2020, 07:34
1 ответ

1. Использование AWK

Вот возможное решение более общей проблемы добавления строки к маркированному блоку текста (, т. е. строк текста, которые следуют за определенной меткой в ​​файле и предшествуют следующей метке. или строку -из -файла ), только если строка еще не существует.

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

tac file | awk '
    /^force_https_protocol=PROTOCOL_TLSv1_2$/ {
        seen = 1
    }
    /^\[security\]$/ {
        if ( ! seen ) {
            print "force_https_protocol=PROTOCOL_TLSv1_2"
        }
    }
    /^\[[^]]*\]$/ {
        seen = 0
    }
    1' | tac

tac, включенный в GNU Coreutils , объединяет и реверсирует файлы построчно. Как реверсировать файл с помощью других/стандартных инструментов описано в нескольких вопросах/ответах по U&L (, например, Как команда sed '1!G;h;$!d' реверсирует содержимое файла ? и Обратный поиск).

Это не будет вставлять force_https_protocol=PROTOCOL_TLSv1_2после первого [security]в следующем фрагменте текста:

[security]
keysdir=/var/lib/ambari-agent/keys
force_https_protocol=PROTOCOL_TLSv1_2
passphrase_env_var_name=AMBARI_PASSPHRASE

[security]
...

Чтобы просто вставить строку после каждого вхождения метки, если строка уже не существует,тот же подход может привести к:

tac file | awk '
    /^force_https_protocol=PROTOCOL_TLSv1_2$/ {
        seen = NR
    }
    /^\[security\]$/ {
        if ( ( NR == 1 ) || ! ( NR == seen + 1 ) ) {
            print "force_https_protocol=PROTOCOL_TLSv1_2"
        }
    }
    1' | tac

(Это будет вставлять force_https_protocol=PROTOCOL_TLSv1_2после [security]в приведенном выше текстовом образце ).

2. Использование sed

С помощью sedвы можете использовать вариант цикла N;P;D;(, который подробно описан в других вопросах/ответах по U&L; например:Как я могу использовать sed для замены многострочной строки -? или Как редактировать следующую строку после шаблона с помощью sed?).

Это вставит строку force_https_protocol=PROTOCOL_TLSv1_2после строки, состоящей исключительно из [security], только если первой еще нет.

sed '
  $! {
    N
    P
    /^\[security\]\n/ {
      /\nforce_https_protocol=PROTOCOL_TLSv1_2$/ b b
      i\
force_https_protocol=PROTOCOL_TLSv1_2
    }
    :b
    D
  }
  s/^\[security\]$/&\
force_https_protocol=PROTOCOL_TLSv1_2/'

Этот скрипт:

  • для каждой строки, кроме последней ($!), добавляет новую строку, за которой следует следующая строка, в пространство шаблонов (N)(, которое уже содержит текущую строку );
  • печатает первую строку в пространстве шаблонов(P); если эта строка [security]...
    • ...и следующая строка force_https_protocol=PROTOCOL_TLSv1_2, просто удаляет первую строку из пространства шаблонов и запускает новый цикл (b b,:b D);
    • в противном случае выводит force_https_protocol=PROTOCOL_TLSv1_2на стандартный вывод(i\)перед удалением первой строки из пространства шаблонов и запуском нового цикла(D);
  • , если последней строкой является [security], заменяет ее самой собой, за которой следует перевод строки и force_https_protocol=PROTOCOL_TLSv1_2и печатает результат (посредством подразумеваемогоp).
0
28.04.2021, 23:20

Теги

Похожие вопросы