bashmacossedbsd

Issue when using sed in combination with read


I am having a problem with sed. Basically, I want to insert some text after a match a small piece of Java code after a match. It seems to be somehow interpreted as something else and ends up failing.

Consider the following basic example that does what I want:

match="string_I_want_to_match"
str_i_want_above="str I want above"

echo $match | sed -e "/$match/i \\
$str_i_want_above"

outputs what I want:

xyzt
string_I_want_to_match

However, if I use read to create a multiline string, it fails with an obscure error. Consider the following example:

match="string_I_want_to_match"

read -r -d '' str_i_want_above <<- 'EOF'
> I
> Want
> This
> Above the match
EOF

echo $match | sed -e "/$match/i \\
$str_i_want_above"

I expect

I
Want
This
Above the match
string_I_want_to_match

but instead I get

sed: 3: "/string_I_want_to_match ...": invalid command code W

It's somehow failing when trying to interpret the second line. I have isolated this to be a problem with read but if I'm wrong, I'd like to understand why and to fix this.

I'm using BSD sed on mac 12.6. I would like to achieve this with sed and read because I need to do in-place replacing and this is going to be a larger script where I need to do several in-place insertions of multiline strings


Solution

  • You need to insert a \ before the line breaks in replacement, so you may use:

    match="string_I_want_to_match"
    
    echo "$match" | sed "/$match/i \\
    > ${str_i_want_above//$'\n'/\\$'\n'}
    > "
    
    I
    Want
    This
    Above the match
    string_I_want_to_match
    

    Here:

    Code Demo