Laurent GRENIER
Laurent GRENIER

Reputation: 632

replace in text with a var with some new lines

I have a var $MY_VAR which contains some new lines:

      hostAliases:
      - ip: "?.?.?.?"
        hostnames:
        - "m-0.mongodb-service.default.svc.cluster.local"
      - ip: "?.?.?.?"
        hostnames:
        - "m-1.mongodb-service.default.svc.cluster.local"
      - ip: "?.?.?.?"
        hostnames:
        - "m-2.mongodb-service.default.svc.cluster.local"
      - ip: "?.?.?.?"
        hostnames:
        - "m-3.mongodb-service.default.svc.cluster.local"

And a file my_file.txt with a value that has to be replaced:

some indented content ...
@@MY_VALUE@@
some indented content ...

I try to replace it using:

sed -i 's,@@MY_VALUE@@,'"$MY_VAR"',g' my_file.txt

That results into the following error:

sed: -e expression #1, char 36: unterminated `s' command

Upvotes: 0

Views: 58

Answers (3)

Laurent GRENIER
Laurent GRENIER

Reputation: 632

I finally found a totally different solution by removing the value to replace and split my file into two parts: my_file_part1.txt and my_file_part2.txt which are respectively the part before the variable and the part after the variable.

touch my_file.txt
cat my_file_part1.txt >> my_file.txt
echo "$MY_VAR" >> my_file.txt
cat my_file_part2.txt >> my_file.txt

Upvotes: 0

anubhava
anubhava

Reputation: 785008

There is no need to do:

MY_VAR=$(cat content.txt)

To first read file content into a variable and then replace a text in second file with this variable's content.

You may use this sed to do this in single step:

sed '/@@MY_VALUE@@/{s///;
r content.txt
}' my_file.txt

some indented content ...

some indented content ...

      hostAliases:
      - ip: "?.?.?.?"
        hostnames:
        - "m-0.mongodb-service.default.svc.cluster.local"
      - ip: "?.?.?.?"
        hostnames:
        - "m-1.mongodb-service.default.svc.cluster.local"
      - ip: "?.?.?.?"
        hostnames:
        - "m-2.mongodb-service.default.svc.cluster.local"
      - ip: "?.?.?.?"
        hostnames:
        - "m-3.mongodb-service.default.svc.cluster.local"
some indented content ...

Update:

You may use this awk to replace a pattern with a multiline variable:

awk -v var="$var" '/@@MY_VALUE@@/{$0 = var} 1' my_file.txt

To save changes inline use this option if using gnu awl:

awk -i inplace -v var="$var" '/@@MY_VALUE@@/{$0 = var} 1' my_file.txt

If not using gnu awk then use:

awk -v var="$var" '/@@MY_VALUE@@/{$0 = var} 1' my_file.txt >> $$.tmp &&
mv $$.tmp my_file.txt

Upvotes: 1

that other guy
that other guy

Reputation: 123440

Here's an easier way to reproduce your problem:

sed -e 's/foo/hello
world/'

Instead of replacing foo with two lines, it shows sed: -e expression #1, char 11: unterminated `s' command

This is because linefeeds end the command. You have to escape them with backslashes:

sed -e 's/foo/hello\
world/'

You can do this in your variable with Bash's parameter expansion (${var//search/replace}):

sed "s/@@MY_VALUE@@/${var//$'\n'/$'\\\n'}/"

Upvotes: 0

Related Questions