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

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

Используя sed (GNU sed) 4.2.2, я хочу:

  1. СоответствоватьLine1
  2. Проверьте Line2, чуть ниже Line1, равно ли оноString
  3. Если нет - добавьте Stringпосле Line1(или вставьте перед Line2)

Что я пробовал:

echo -e "Line1\nLine2\nLine3" | sed '/Line1/n;/^String$/!iString'

но он возвращает:

Строка1
Строка
Строка2
Строка
Строка3

Я также попробовал:

echo -e "Line1\nLine2\nLine3" | sed '/Line1/{n;/^String$/!iString}'

но он возвращается

sed: -e выражение #1, символ 0: несоответствующий `{'

Я знаю, как это сделать по-другому, также с помощью sed, но я пытаюсь понять, как добиться этого именно так, как я описал выше. Также, пожалуйста, скажите мне, что не так с моим кодом.

решение1

Пытаться:

sed '/Line1/{N; /\nString$/b; s/\n/\nString\n/}' file

Ограничение: Если две строки с Line1появляются подряд, это может привести к желаемому результату, а может и нет.

Пример

Давайте рассмотрим этот тестовый файл:

$ cat file
Line1
String
Line2
String
Line3
Line1
Line2

И давайте применим нашу команду:

$ sed '/Line1/{N; /\nString$/b; s/\n/\nString\n/}' file
Line1
String
Line2
String
Line3
Line1
String
Line2

Как это работает

  • Line1/{...}

    Это выполнит команды в фигурных скобках только в том случае, если текущая строка соответствует регулярному выражению Line1.

  • N

    Это считывает следующую строку и добавляет ее к текущей строке, разделяя две строки символом новой строки.

  • /\nString$/b

    Если вторая строка соответствует регулярному выражению \nString$, то пропустите оставшиеся команды («branch», b).

  • s/\n/\nString\n/

    Это заменит символ новой строки, разделяющий первую и вторую строки, на символ новой строки, за которым Stringследует еще один символ новой строки.

Связанный контент