When using pipe with or without global g option gives same result:
echo -e 'hi\nhello\nhi' | sed '1s/hi/hey/g'
hey
hello
hi
works for here-string as well when not using global g option:
sed '1s/hi/hey/' <<< $(echo -e 'hi\nhello\nhi')
hey hello hi
but when using global g option and here-string replaces the pattern at every line:
sed '1s/hi/hey/g' <<< $(echo -e 'hi\nhello\nhi')
hey hello hey
Why this change in the output when using the global substitution flag and when input comes through here-string?
It's not got much to do with the sed
script and does have a lot to do with the bash
here-string notation and quotes. Use cat
instead of sed
and you see:
$ echo -e 'hi\nhello\nhi' | cat
hi
hello
hi
$ cat <<< $(echo -e 'hi\nhello\nhi')
hi hello hi
$ cat <<< "$(echo -e 'hi\nhello\nhi')"
hi
hello
hi
$
So, you can see that with the unquoted here-string, you get three words on one line. The g
modifier on the sed
command 1s/hi/hey/g
means that both occurrences of hi
on the first line of input are changed. In the absence of the g
modifier, only the first occurrence on the first line is changed. The third line never gets modified because the 1
in 1s/hi/hey/
limits the changes to the first line of input.
This also explains the 3 lines vs 1 line of output.