sed replace with variable with multiple lines
Solution 1
An interesting question..
This may get you closer to a solution for your use case.
read -r -d '' TEST <<EOI
a\\
b\\
c
EOI
echo TOREPLACE | sed -e "s/TOREPLACE/${TEST}/"
a
b
c
I hope this helps.
Solution 2
Given that you're using Bash, you can use it to substitute \n
for the newlines:
sed -e "s/TOREPLACE/${TEST//$'\n'/\\n}/" file.txt
To be properly robust, you'll want to escape /
, &
and \
, too:
TEST="${TEST//\\/\\\\}"
TEST="${TEST//\//\\/}"
TEST="${TEST//&/\\&}"
TEST="${TEST//$'\n'/\\n}"
sed -e "s/TOREPLACE/$TEST/" file.txt
If your match is for a whole line and you're using GNU sed, then it might be easier to use its r
command instead:
sed -e $'/TOREPLACE/{;z;r/dev/stdin\n}' file.txt <<<"$TEST"
Solution 3
You can just write the script as follows:
sed -e 's/TOREPLACE/a\
b\
c\
/g' file.txt
A little cryptic, but it works. Note also that the file won't be modified in place unless you use the -i
option.
Solution 4
tricky... but my solution would be :-
read -r -d '' TEST <<EOI
a
b
c
EOI
sed -e "s/TOREPLACE/`echo "$TEST"|awk '{printf("%s\\\\n", $0);}'|sed -e 's/\\\n$//'`/g" file.txt
Important: Make sure you use the correct backticks, single quotes, double quotes and spaces else it will not work.
Andreas
Updated on July 31, 2022Comments
-
Andreas over 1 year
I am trying to replace a word with a text which spans multiple lines. I know that I can simply use the newline character \n to solve this problem, but I want to keep the string "clean" of any unwanted formatting.
The below example obviously does not work:
read -r -d '' TEST <<EOI a b c EOI sed -e "s/TOREPLACE/${TEST}/" file.txt
Any ideas of how to achieve this WITHOUT modifying the part which starts with read and ends with EOI?
-
Andreas almost 13 yearsThanks. I know about the -i option. Actually, I want to use a variable for better readability and I do not want to touch the contents of the variable. Actually ... it's rather that I would like to know how I can do this for future reference. Do you know a solution to this problem that does not involve the modification of the first 5 lines?
-
Diego Sevilla almost 13 yearsThe question is that the
read
converts the carriage returns into spaces, so you should be inserting the carriage returns again anyway. -
Andreas over 12 yearsFor the moment I will go with this ... interestingly, that doesn't seem to be as trivial as I thought it was ... thanks