sedsubstitution

Is it possible to tell sed to perform a maximum of one substitution command per line?


Is it possible to encapsulate the following pseudocode using sed?

for line in lines:
    if line == "foo":
        print "FOO"
    else:
        print "- " + line

Here's the first thing I tried:

> echo 'foo
> bar
> baz' | sed -e 's/^foo$/FOO/' -e 's/^/- /'
- FOO
- bar
- baz

This is incorrect since both substitutions are applied to the first line.

Is it possible to tell sed to perform a maximum of one substitution per line?


Solution

  • You can limit what lines a substitution affects, by prefixing it with a pattern:

    sed -e '/^foo$/! s/^/- /' -e '/^foo$/ s//FOO/' infile
    

    A better alternative is to use the t branch command which will go to the next line if the previous substitution succeeded:

    sed 's/^foo$/FOO/; t; s/^/- /' infile
    

    Or the more portable:

    sed -e 's/^foo$/FOO/' -e t -e 's/^/- /' infile
    

    Output in both cases:

    FOO
    - bar
    - baz