Я создал тест, используя grep
, но он не работает в sed
.
grep -P '(?<=foo)bar' file.txt
Это работает правильно, возвращая bar
.
sed 's/(?<=foo)bar/test/g' file.txt
Я ожидал footest
в качестве вывода, но это не сработало.
Я создал тест, используя grep
, но он не работает в sed
.
grep -P '(?<=foo)bar' file.txt
Это работает правильно, возвращая bar
.
sed 's/(?<=foo)bar/test/g' file.txt
Я ожидал footest
в качестве вывода, но это не сработало.
GNU sed не поддерживает утверждения просмотра. Вы можете использовать более мощный язык, такой как Perl, или поэкспериментировать с ssed
, который поддерживает регулярные выражения в стиле Perl.
perl -pe 's/(?<=foo)bar/test/g' file.txt
Обратите внимание, что в большинстве случаев вы можете избежать просмотра назад (или просмотра вперед), используя группу захвата и обратную ссылку в строке замены:
sed 's/\(foo\)bar/\1test/g' file.txt
Имитация отрицательного взгляда назад более тонкая и требует нескольких замен для защиты подстроки, которую вы хотите избежать. Пример для (?<!foo)bar
:
sed 's/#/##/g;s/foobar/foob#ar/g;s/bar/test/g;s/foob#ar/foobar/g;s/##/#/g' file.txt
#
=> ##
).foobar
, => foob#ar
или ba
=> b#a
).foob#ar
на foobar
(или b#a
на ba
).##
на #
.Очевидно, вы также можете описать все, что не foo
до bar
:
sed -E 's/(^.{0,2}|[^f]..|[^o].?)bar/\1test/g' file.txt
Но это будет быстро привередливым с большим количеством символов.
#
=> ##
). 2) включите этот символ в подстроку, которую вы хотите защитить (здесь foobar
=> foob#ar
). 3) произвести замену. 4) заменить foob#ar
на foobar
. 5) заменить ##
на #
. Пример с sed: sed 's/#/##/g;s/foobar/foob#ar/g;s/bar/test/g;s/foob#ar/foobar/g;s/##/#/g' <<<'abc foobar # foob#ar foo bar'
- person Casimir et Hippolyte; 11.06.2020
foobar
=›-#-
(вместо foob#ar) было бы понятнее), затем вы находите и заменяете все остальные, затем ставите защищенные назад
- person Max; 11.06.2020
foobar
=> -#-
: если хотите (и только если вы ранее заменили все #
на ##
).
- person Casimir et Hippolyte; 11.06.2020