Search code examples
bashshellsedgrepnon-greedy

Same pattern in grep and sed select different values


I want to create a pattern for sed, which will find out 'type="" For this I tried to use the pattern

type=".*\?"

echo 'aa type="none" stretchChildren="first"' | sed s/'type=".*\?"'/hello/

Above is the sed command which prints

aa hello

Which means it selects 'type="none" stretchChildren="first"' for 'type=".*\?"'

Now below is the grep command using same pattern on same string

 echo 'aa type="none" stretchChildren="first"' | grep -oP 'type=".*?"'

It gives output

type="none"

Don't know what I am missing in sed pattern

Can some one help me out here Output of sed should be

aa hello stretchChildren="first"


Solution

  • sed doesn't have non-greedy pattern matching, so using *? or *\? won't work.

    If you want to have the same output as grep then use a grouping without the " - [^"]+ instead of ".*?":

    sed -r 's/type="[^"]+"/hello/'
    

    [, ] is a group of characters, ^ is a negation, so [^"] means any character that is not a ".

    For OSX use -E instead of -r. (-E also works on latest GNU sed, but it is not documented in --help nor in man sed so I don't recommend it)