Replace only the first occurence matching a regex with sed

10,563

Solution 1

If I understand your question, you want strings like test:growTest:ret to become growTest:ret.

You can use:

sed -i 's/test:(.*$)/\1/'

i means edit in place.

s/one/two/ replaces occurences of one with two.

So this replaces "test:(.*$)" with "\1". Where \1 is the contents of the first group, which is what the regex matched inside the braces.

"test:(.*$)" matches the first occurence of "test:" and then puts everything else until the end of the line unto the braces. The contents of the braces remain after the sed command.

Solution 2

Modify your regexp ^.*: to ^[^:]*:

All you need is that the .* construction won't consume your delimiter — the colon. To do this, replace matching-any-char . with negated brackets: [^abc], that match any char except specified.

Also, don't confuse the two circumflexes ^, as they have different meanings: first one matches beginning of string, second one means negated brackets.

Solution 3

  1. Sed use hungry match. So ^.*: will match test:growTest: other than test:.
  2. Default, sed only replace the first matched pattern. So you need not do anything specially.
Share:
10,563
Unitech
Author by

Unitech

Updated on June 30, 2022

Comments

  • Unitech
    Unitech almost 2 years

    I have a string

    test:growTest:ret
    

    And with sed i would to delete only test: to get :

    growTest:ret
    

    I tried with

    sed '0,/RE/s/^.*://'
    

    But it only gives me

    ret
    

    Any ideas ?

    Thanks

  • sbrattla
    sbrattla almost 6 years
    Does this require a particular version of sed. I get sed: -e expression #1, char 16: invalid reference \1 on s' command's RHS` when i try that one.
  • Roel Van de Paar
    Roel Van de Paar almost 5 years
    There looks to be a bug in the answer. Isn't it sed -i 's/test:\(.*$\)/\1/' instead? i.e. the selectors ( and ) always need a \ backslash prefix.