Регулярное выражение Sed и отрицание подстроки
Каков правильный синтаксис для поиска подстроки (строка, которой предшествуют и следуют определенные строки), которая соответствует не конкретному шаблону?
Например, я хочу взять все подстроки, которые начинаются с BEGIN_
, заканчиваются на _END
, а подстрока между ними не равна FOO
; и заменить всю подстроку на формат "(внутренняя подстрока)". Следующее будет соответствовать:
-
BEGIN_bar_END
→ (bar)
-
BEGIN_buz_END
→ (buz)
-
BEGIN_ihfd8f398IHFf9f39_END
→ (ihfd8f398IHFf9f39)
Но BEGIN_FOO_END
не соответствует.
Я играл со следующим, но не могу найти правильный синтаксис:
sed -e 's/BEGIN_(^FOO)_END/($1)/g'
sed -e 's/BEGIN_([^FOO])_END/($1)/g'
sed -e 's/BEGIN_(?!FOO)_END/($1)/g'
sed -e 's/BEGIN_(!FOO)_END/($1)/g'
sed -e 's/BEGIN_(FOO)!_END/($1)/g'
sed -e 's/BEGIN_!(FOO)_END/($1)/g'
Ответы
Ответ 1
В Sed, IIRC нет общего оператора отрицания, поскольку компиляция регулярных выражений с отрицанием DFA занимает экспоненциальное время. Вы можете обойти это с помощью
'/BEGIN_FOO_END/b; s/BEGIN_\(.*\)_END/(\1)/g'
где /BEGIN_FOO_END/b
означает: если мы найдем BEGIN_FOO_END
, то ветвь (прыжок) в конец Sed script.
Ответ 2
Этот вопрос может быть старым, но для полноты, как насчет оператора отрицания !
:
Сделать всех несчастных ОЧЕНЬ СЧАСТЛИВОЙ:
echo -e 'happy\nhappy\nunhappy\nhappy' | sed '/^happy/! s/.*/VERY HAPPY/'
Найдено здесь: Как глобально заменить строки в строках NOT, начиная с определенного шаблона
Ответ 3
Это может сработать для вас:
sed 'h;s/BEGIN_\(.*\)_END/(\1)/;/^(FOO)$/g' file
Это работает только в том случае, если в строке есть только одна строка.
Для нескольких строк в строке:
sed 's/BEGIN_\([^F][^_]*\|F[^O][^_]*\|FO[^O][^_]*\|FOO[^_]\+\)_END/\(\1\)/g' file
Или легче понять:
sed 's/\(BEGIN_\)FOO\(_END\)/\1\n\2/g;s/BEGIN_\([^\n_]*\)_END/(\1\)/g;s/\n/FOO/g' file
Ответ 4
Я не знаю, как это сделать, но вы всегда можете это сделать:
$ cat file
BEGIN_FOO_END
BEGIN_FrOO_END
BEGIN_rFOO_END
$ sed '/BEGIN_FOO_END/ !{s/BEGIN_\([^_]*\)_END/(\1)/}' file
BEGIN_FOO_END
(FrOO)
(rFOO)