
Используя sed (GNU sed) 4.2.2, я хочу:
- Соответствовать
Line1
- Проверьте
Line2
, чуть нижеLine1
, равно ли оноString
- Если нет - добавьте
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
следует еще один символ новой строки.