Use sed to find whole word and replace

22,337

Solution 1

Is this what you want?

$ sed 's/\(^\| \)test3\( \|$\)/\1/g' file
test3.legacy test4.legacy test3.kami

This say

substitute
   (^ start of line OR space)
   test3
   (space OR end of line)
with match 1 (AKA space or start of line)

Update:

And as so elegantly put by the good @Stephane Chazelas this would not take care of certain cases. Also emphasize on the portability part. See answer below.

A GNU variant could, (hopefully), be:

sed 's/\(^\| \)\(test3\( \|$\)\)*/\1/g'
# Or perhaps:
sed 's/\(^\| \)\(test3\( \|$\)\)\+/\1/g'

taking care of repetitive matches. Optionally one would take care of multiple spaces etc as well. Depending on input.

EOUPD


As an alternative perhaps (only meant as a starting point):

sed 's/\Wtest3\W/ /g'

Not this I assume:

$ sed 's/test3\.\?[^ ]* *//g' file
test4.legacy

Solution 2

Portably:

sed -e 's/.*/ & /' -e :1 -e 's/ test3 / /g;t1' -e 's/^ //;s/ $//'

That is:

  • first add a space at the beginning and end of the line, to not have to consider test3 at the beginning and end specially,
  • replace test3 enclosed in spaces with a single space,
  • repeat the process as long as there are substitutions (to cover the test3 test3 cases).
  • Remove the leading and trailing space that we added initially.

Solution 3

I'd look for test3 wrapped with a space on either side, \s, given your example rather than try and use the word boundary notation.

For example

$ echo "test3.legacy test4.legacy test3 test3.kami" | sed 's/\stest3\s/ /g'
test3.legacy test4.legacy test3.kami

The above looks for space test3 space and replaces this with just a space.

NOTE: This won't handle the situation where test3 is first in the list!

Share:
22,337

Related videos on Youtube

user3779606
Author by

user3779606

Updated on September 18, 2022

Comments

  • user3779606
    user3779606 over 1 year

    I have the following block of text in a file:

    test3.legacy test4.legacy test3 test3.kami
    

    I only want to search for test3 as a whole and replace it with nothing. Unfortunately, all my attempts have removed test3 from test3.legacy and test3.kami. I've tried:

    sed 's/^test3://g' myfile.txt
    sed 's/\btest3\b//g' myfile.txt
    sed 's/\<test3\>//g' myfile.txt
    

    without any luck. Any ideas how I can resolve this please?

    EDIT: Most attempts have resulted in the following: .legacy test4.legacy .kami

  • user3779606
    user3779606 almost 11 years
    Sukminder, the first command was perfect! Thank you! Would you mind explaining the reason for the pipes (|)?
  • Runium
    Runium almost 11 years
    It is not perfect as to if start or end of line. Correcting.
  • user3779606
    user3779606 almost 11 years
    Hi slm, Thank you for the response. Your solution makes sense and also works.
  • Runium
    Runium almost 11 years
    @slm; heh ;). still one flaw, it would result in trailing space if last word is test3. But guess it is better with a trailing space then one at start. One can overcome this as well though.
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    Note that none of \|, \W or \? are standard sed. So the above will work with GNU sed, but probably not many others.
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    Note that \s is a GNU extension (inspired by perl) and is short for the standard [[:space:]], not [[:blank:]], that is it includes all the horizontal and vertical spacing characters, not just tab and space. It is also locale dependant. Your solution would also fail to remove the second test3 in "x test3 test3 y"
  • slm
    slm almost 11 years
    @StephaneChazelas, thanks for the improvement. Question, is it better to adjust our answers in situations like this or leave them and let the comments pick up these nuances? You've corrected a couple of my answers, which I appreciate, since I'm learning like everyone else, but I wasn't sure what was the correct thing to do?
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    Up to you really. I'm not sure there's some consensus on that. You can always ask on meta. Nothing wrong in editing the answer to improve or point out the limitations even if you come to realise that through others' comments IMO.
  • Runium
    Runium almost 11 years
    @StephaneChazelas: Thank you. The second was only meant as a starter – though by not expressing it who can know. Hope my update is more correct.
  • Anthon
    Anthon about 9 years
    This is not going to delete the first t from test3.kami from the block of text as well