Search code examples
sedbsd

BSD sed (Mac) How to replace from nth occurrence till the end of the line?


In GNU sed it will be something like this

's/foo/bar/3g' <<< "foofoofoofoofoo"

Output: "foofoobarbarbar"

The same command in BSD sed gives me a following error

sed: 1: "s/foo/bar/3g": more than one number or 'g' in substitute flags

How can I implement this on BSD sed?

I searched SO and found this but all the answers are for GNU. I read the man but am having a difficulty figuring this out.


Solution

  • One option is implementing a loop using a label and t command:

    $ sed -e ':l' -e 's/foo/bar/3' -e 'tl' <<< 'foofoofoofoofoo'
    foofoobarbarbar
    

    Just be careful because if your replacement text is matched by your original RE (e.g. s/f.x/fox/) then you'll be stuck in an infinite loop and if it generates the original text after replacement then you'll get unexpected results, e.g.:

    $ sed 's/foo/oo/3g' <<< 'foofoofffoo'
    foofooffoo
    
    $ sed -e ':l' -e 's/foo/oo/3' -e 'tl' <<< 'foofoofffoo'
    foofoooo
    

    Note above that the first version works because it's doing all replacements in 1 pass of the text so the previous replacement isn't considered part of the string for the current replacement pass.