2

We have the following line in a file on Linux:

discovery.uri=http://master.navada.com:8800

we want to add the word koko before master, so I just do:

sed –i 's/master/kokomaster/' file

which gives:

discovery.uri=http://kokomaster.navada.com:8800

but what we want is to add koko only if koko isn't already present before master.

For example, the next time that we run

sed –i 's/master/kokomaster/' file

the line will be:

discovery.uri=http://kokokokomaster.navada.com:8800
4

You can replace a bit more to avoid this problem:

sed -i sX/masterX/kokomasterX file

This replaces “/master”, so the next time you run it, nothing will be replaced, since “/kokomaster” doesn’t match.

4
sed -i '/kokomaster/!s/master/koko&/' file

First test whether the string kokomaster exists on the line, and if it doesn't, do the substitution. This is almost a literal translation of "but what we want is to add the koko word only if koko not exists before master word" into sed.

The & in the replacement part of the substitution will be replaced by the text matched by the pattern part (i.e. master).


After reading the comments (see below), you may want to use something more specific that would actually only modify the server name portion of the URI, and not any master string elsewhere, even if kokomaster occurred (or not) in the URI path:

sed -i 's,^\(discovery\.uri=http://\)\(master\),\1koko\2,' file

You may even want to go as far as matching the exact and full line that you'd want to replace, just to avoid even hypothetical mistakes:

sed -i 's,^\(discovery\.uri=http://\)\(master\.navada\.com:8800\)$,\1koko\2,' file

If the configuration file is written in JSON or some other well know format, you would not use sed at all, but jq or some other apropriate tool specifically written for handling files of that format.

  • 1
    That wouldn't work on discovery.uri=http://master.navada.com:8800/kokomaster though. – Stéphane Chazelas Jun 6 at 13:54
  • @StéphaneChazelas Correct, as per the explicit specification from the user. – Kusalananda Jun 6 at 14:51
  • Not sure I follow. In discovery.uri=http://master.navada.com:8800/kokomaster, there's no koko before the first master. Yet, that sed line doesn't add one. – Stéphane Chazelas Jun 6 at 14:54
  • @StéphaneChazelas Sorry, that was half a joke, but it is actually what the user specified. If the string koko does not already occur before master, it should not be added again. That's what's requested, and that's what I did, pedantically following the request to the letter. In your string, koko already occurs right before master, so it's not added again. – Kusalananda Jun 6 at 15:35
  • @Kusalananda nope. The master in the server name needs to be replaced even if there may be some kokomaster in the path. Pedanticly. I guess the OP doesn't care. – Philippos Jun 6 at 16:32
3

Use

sed 's/\(koko\)*master/kokomaster/'

so master and any number of preceeding kokos get replaced.

  • Or better, sed 's/\(koko\)\{0,1\}master/kokomaster/' to avoid replacing kokokokomaster with kokomaster. – Stéphane Chazelas Jun 6 at 13:52
2

If you're open to other tools:

perl -i -pe 's/(?<!koko)master/kokomaster/' file

The (?>!foo) is a negative lookbehind, so (?<!koko)master will only match master when not preceded by koko.

2

I have used below awk command to do the same

command

awk '$0 !~/kokomaster/{gsub("master","kokomaster",$0)}1'  filename >file_tmp && mv file_tmp filename

output

discovery.uri=http://kokomaster.navada.com:8800
discovery.uri=http://kokomaster.navada.com:8800

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.