Edwin
Edwin

Reputation: 2278

linux sed substitusion with regex fails

So I have the following regex that works, but not with sed

regex101

^(\S*HTTPS*_SERVER\S*)(\s*'https*:\/\/)(\S*)('\);)$

and the text in my file.txt:

define('HTTP_SERVER', 'http://localhost:31270');
define('HTTPS_SERVER', 'https://localhost:31270');

then when I try to do:

sed -i.bak -r 's/^\(\S*HTTPS*_SERVER\S*\)\(\s*\'https*:\/\/\)\(\S*\)\(\'\);\)$/\1\2test.com\4/' file.txt

it doesn't do anything.

Any ideas what it is wrong here? Is it because of the escaping char?

Upvotes: 1

Views: 25

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626845

Since you are using POSIX ERE syntax (-r option) a capturing group is defined with a pair of unescaped ( and ). Besides, since you have a ' inside the pattern, you need to use doulbe quotes around the s/.../.../ command.

Use

sed -i.bak -r "s/^(\S*HTTPS*_SERVER\S*)(\s*'https*:\/\/)(\S*)('\);)$/\1\2test.com\4/" file.txt

See an online demo.

Note that you may use delimiters other than / to avoid escaping / symbols, in the pattern (say, you may use "s,<pattern>,<replacement>,", as there are no commas in the pattern itself). Besdies, as per this thread, if you really need to use a single quoted regex definition, you may replace a literal ' in the pattern with a \x27 entity.

Also, if you need not insert any text in between Group 1 and Group 2, you may merge the two group patterns into one, and - as you are removing Group 3, you do not even need to capture it.

So, an alternative could look like

sed -r 's,^(\S*HTTPS*_SERVER\S*\s*\x27https*://)\S*(\x27\);)$,\1test.com\2,' file.txt

See another online demo.

Upvotes: 1

SLePort
SLePort

Reputation: 15461

You can reduce the number of capturing groups:

sed -E -i.bak "s/^(define\('HTTPS?_SERVER', 'https?:\/\/)[^']*('\);)/\1test.com\2/" file.txt

Upvotes: 1

Related Questions