sed delete между двумя шаблонами удаляет до конца, если второй шаблон не найден - PullRequest
2 голосов
/ 08 января 2020

Я использую sed для удаления тегов в файле конфигурации, но я случайно наткнулся на проблему, для которой я буду использовать базовый пример c:

Содержимое numbers.txt file:

0
1
2
3
4
5
6
7
8
9

Удалить между двумя числами (включая сами числа):

sed '/4/,/6/d' numbers.txt

Выход (как и ожидалось):

0
1
2
3
7
8
9

Но если я удалю в строке 6 из numbers.txt можно ожидать, что та же команда выдаст all из numbers.txt, поскольку она не может найти второй шаблон, но вместо этого просто удаляет все после строки 4 ( предположительно потому, что поиск 6 достиг конца файла, и вот значение, которое он возвращает):

0
1
2
3

Мой вопрос: как мне изменить оператор sed, чтобы он просто ничего не делал в такое событие?

1 Ответ

3 голосов
/ 08 января 2020

Это может работать для вас (GNU sed):

sed '/4/{:a;$!{N;/6/Md;ba}}' file

Создайте свой собственный l oop и удаляйте только накопленные строки в пространстве образца, если выполнено условие конца.

NB Флаг M в конечном состоянии разрешает совпадения для нескольких строк, собранных в пространстве образца.

/start/,/end/d - это структура управления, которая при обнаружении start немедленно удаляет строки до end или конец файла. Поэтому существует два условия end , адрес /end/ или $. Поскольку действие (в данном случае удаление) является немедленным, его нельзя отменить, если не выполнено условие /end/, по этой причине подлежащие удалению строки должны быть собраны и удалены или не зависеть от одного из двух условий, * /end/ (удалить) или $ (не удалять).

  • /4/{...} начальный адрес действий в фигурных скобках.
  • :a адрес начало al oop с именем a
  • $!{...}, если не конец действия с файлом в фигурных скобках.
  • N добавьте новую строку, а затем следующую строку в пространство шаблона.
  • /6/Md конечный адрес и команда удаления, если найдены, т.е. это удалит все строки в пространстве шаблона, которые были добавлены командой N.
  • ba команда goto, прерывается на адрес l oop a. Это позволяет механизму l oop продолжаться до тех пор, пока одно из двух условий /6/ или $.

NB Если условие конца файла выполнено, /4/{...} заканчивается и накопленное строки печатаются как обычно.

...