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

If have the file:

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

Would execute:

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

Which results to: srv-db srv-db-2 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


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\>/\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.

  • But none of them has worked perfectly is this particular case. - why not? Nov 11, 2016 at 14:19
  • because of the dash...(-) at the end of the string inside of the file.
    – Evis
    Nov 11, 2016 at 14:26
  • Please edit your question and add the complete command that you used and what the result was. This gives "us" something tangible to chew on. Nov 11, 2016 at 14:29

1 Answer 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-])/'


grep -P '\bsrv-db(?![\w-])'
  • 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:]]|$)/\2/" /etc/hosts
    – Evis
    Nov 11, 2016 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, 2016 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. Nov 11, 2016 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|$))/\2\3/" /etc/hosts` Thanks you very much!
    – Evis
    Nov 11, 2016 at 15:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .