1

There two steps, first check if exist the host in the file

If have the file:

# FILE: /etc/hosts:
192.168.0.10 srv-db srv-db-home
192.168.0.15 srv-db1
192.168.0.20 srv-db-2
192.168.0.20 srv-db-work srv-db-

Would execute:

sed -n -e '/\<srv-db\>/p' /etc/hosts

Which results to:

192.168.0.10 srv-db
192.168.0.20 srv-db-2
192.168.0.20 srv-db-

It ignores the number at the end just fine... but it does not ignore the dash (-).

I have found a bunch of regex that works parcially... as these two below:

Match exact string using grep

and

How to match exact string using `sed`? But not the part of it.?

The answer below from @steeldriver helped with that:

awk '$NF == "srv-db"' /etc/hosts

But, when going to update the IP Address, it becames fuzzy, here is the full code I have camed up with:

sed -i -e "s/\(^ *[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\(\s*\)\<srv-db\>/192.168.9.9\2/" /etc/hosts

It should update only the first line, but instead it updates the same results as of above.

But none of them has worked perfectly is this particular case.

Evis
  • 113

1 Answers1

1

The \> word boundary anchor treats - as a boundary.

If you know that there is no trailing whitespace, you could anchor to the end of line /\<srv-db$/ - to allow for trailing whitespace you could modify that to /\<srv-db[[:blank:]]*$/ or /\<srv-db[[:space:]]*$/

Or use awk and do a string match instead:

awk '$NF == "srv-db"' /etc/hosts

If you can't necessarily anchor to the end of line (even with trailing whitespace) then you will beed to construct an expression that (for example) tests for whitespace or end of line (i.e. "word boundary without hyphen") e.g. (using extended regular expression mode)

sed -En -e '/\<srv-db(\s|$)/p'

If you can use perl (or grep in PCRE mode) then there are possibly more elegant options such as

perl -ne 'print if /\bsrv-db(?![\w-])/'

or

grep -P '\bsrv-db(?![\w-])'
steeldriver
  • 81,074
  • When substituing with my formula as of below, it is not working, could you take a look at: sed -i -e "s/\(^ *[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\(\s*\)\<srv-db([[:blank:]]|$)/192.168.9.9\2/" /etc/hosts – Evis Nov 11 '16 at 15:01
  • If I take -E which I have never seen it and could not find in the docs... it will not even bring us the result as expected. – Evis Nov 11 '16 at 15:05
  • 1
    If you're not using -E (extended regex) as indicated by your escaping of the braces, then the 'or' operator | must also be escaped, I think. You need to choose either BRE or ERE mode and stick with it. – steeldriver Nov 11 '16 at 15:06
  • Working: sed -E -e "s/(^ *[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})(\s\*)(\<srv-db(\s|$))/192.168.200.254\2\3/" /etc/hosts Thanks you very much! – Evis Nov 11 '16 at 15:19