I created a test using grep
but it does not work in sed
.
grep -P '(?<=foo)bar' file.txt
This works correctly by returning bar
.
sed 's/(?<=foo)bar/test/g' file.txt
I was expecting footest
as output, but it did not work.
I created a test using grep
but it does not work in sed
.
grep -P '(?<=foo)bar' file.txt
This works correctly by returning bar
.
sed 's/(?<=foo)bar/test/g' file.txt
I was expecting footest
as output, but it did not work.
GNU sed does not have support for lookaround assertions. You could use a more powerful language such as Perl or possibly experiment with ssed
which supports Perl-style regular expressions.
perl -pe 's/(?<=foo)bar/test/g' file.txt
Note that most of the time you can avoid a lookbehind (or a lookahead) using a capture group and a backreference in the replacement string:
sed 's/\(foo\)bar/\1test/g' file.txt
Simulating a negative lookbehind is more subtile and needs several substitutions to protect the substring you want to avoid. Example for (?<!foo)bar
:
sed 's/#/##/g;s/foobar/foob#ar/g;s/bar/test/g;s/foob#ar/foobar/g;s/##/#/g' file.txt
#
=> ##
).foobar
here, => foob#ar
or ba
=> b#a
).foob#ar
with foobar
(or b#a
with ba
).##
with #
.Obviously, you can also describe all that isn't foo
before bar
in a capture group:
sed -E 's/(^.{0,2}|[^f]..|[^o].?)bar/\1test/g' file.txt
But it will quickly become tedious with more characters.
#
=> ##
). 2) include this character in the substring you want to protect (foobar
here, => foob#ar
). 3) make your replacement. 4) replace foob#ar
with foobar
. 5) replace ##
with #
. Example with 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'
–
Ganglion foobar
=>-#-
(instead foob#ar) would be clearer), then you find & replace all others, then you put the "protected" ones back –
Ionian foobar
=> -#-
: if you want (and only if you have replaced all #
with ##
before). –
Ganglion GNU sed does not have support for lookaround assertions. You could use a more powerful language such as Perl or possibly experiment with ssed
which supports Perl-style regular expressions.
perl -pe 's/(?<=foo)bar/test/g' file.txt
sed doesn't support lookarounds but choose (I'm the author) does. It uses PCRE2 syntax.
For example:
$ echo "hello bar foobar" | choose -r --sed '(?<=foo)bar' --replace test
hello bar footest
It's speed is comparable to sed.
© 2022 - 2024 — McMap. All rights reserved.
grep -P
is also a nonstandard extension, though typically available on Linux (but not other platforms). – Metagenesis