TryTryAgain
TryTryAgain

Reputation: 7820

sed - replace match containing two wildcards

I'm having trouble trying to replace a match. My example file:

cat ntpd:

OPTIONS="-g"
OPTIONS="-u ntg:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u root:root -p /var/run/ntpd.pid -g"
OPTIONS="-u root:root"
OPTIONS="-u"

I'd like to replace any occurrence of "-u *:*" with "-u ntp:ntp"

I've tried variants of:

sed 's/-u\ \(.*\)\:\(.*\)/-u ntp:ntp/g' ntpd

but that's giving me results in which everything after the replacement string is being lost:

OPTIONS="-g"
OPTIONS="-u ntp:ntp
OPTIONS="-u ntp:ntp
OPTIONS="-u ntp:ntp
OPTIONS="-u"

....if I add a space after the second wildcard (.*\) like sed 's/-u\ \(.*\)\:\(.*\) /-u ntp:ntp/g' ntpd that strangely results in:

OPTIONS="-g"
OPTIONS="-u ntp:ntp-g"
OPTIONS="-u ntp:ntp-g"
OPTIONS="-u root:root"
OPTIONS="-u"

...where a line in which the pattern match no longer matches because it isn't trailed by a space no longer gets replaced (not good), and the line containing a space and more text after is finding the -g as the only remaining text, but I'd assume it would have left all -p /var/run/ntpd.pid -g trailing text.

Any sed experts out there, any/all guidance is appreciated. My desired results would be:

OPTIONS="-g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp"
OPTIONS="-u"

Upvotes: 0

Views: 69

Answers (3)

TryTryAgain
TryTryAgain

Reputation: 7820

All proposed answers work to a degree, but both have problems (a trailing " is wrongly dropped).

OPTIONS="-g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp
OPTIONS="-u"

Whereas, the comment provided answer by @melpomene was the first response and ultimate solution, for this case at least.

Using sed 's/-u\ [a-zA-Z0-9_-]*:[a-zA-Z0-9_-]*/-u ntp:ntp/g' ntpd

results in the much desired:

OPTIONS="-g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp"
OPTIONS="-u"

Upvotes: 0

potong
potong

Reputation: 58453

This might work for you (GNU sed):

sed -r 's/-u\s\S+:\S+/-u ntp:ntp/' file

Using \s to represent a space and \S to represent a non-space and the qualifier + to represent one or more of the preceeding character or class of characters, the regexp matches a -u followed by a single space, followed by one or more non-spaces, followed by a :, followed by one or more non-spaces.

Upvotes: 0

hek2mgl
hek2mgl

Reputation: 158060

This command should do it:

sed 's/-u\( [^:]\{1,\}:[^ ]\{1,\}\)/-u ntp:ntp/' file

Output:

OPTIONS="-g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -g"
OPTIONS="-u"

Btw, using extended posix regular expressions with -r the command becomes a bit more readable:

sed -r 's/-u( [^:]{1,}:[^ ]{1,})/-u ntp:ntp/' file

Upvotes: 1

Related Questions