sed line number specific substitution changes every pattern on using g option and here-string

446 views Asked by At

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?

1

There are 1 answers

0
Jonathan Leffler On BEST ANSWER

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.