0

So I'm trying to replace a line content in a file with multiple lines but I can't get it to work. Here's the details:

Text File: /home/user1/file1.txt

File content:

The quick brown fox
The quick brown fox jumps over the lazy fat dog
Little brown and the lazy fat dog
Lazy dog and the fat lion

string1="The quick brown fox jumps over the lazy fat dog"

string2="The quick little black fox jumps over the lazy fat dog The quick big brown fox jumps over the lazy fat dog The lazy little brown fox jumps over the lazy fat dog"

Shell script file: /home/user1/replace_me.sh

So if I run the shell script file with the below sid command, the file content would be changed to:

The quick brown fox
The quick little black fox jumps over the lazy fat dog
The quick big brown fox jumps over the lazy fat dog
The lazy little brown fox jumps over the lazy fat dog 
Little brown and the lazy fat dog 
Lazy dog and the fat lion

I used How to replace a variable with another variable using sed and Replace a word with multiple lines using sed? as references:

These are the commands I tried with no luck :(

sed -i "s/$string1/$string2/" /home/user1/file1.txt

sed -i "/${string1}/{s/^.*/${string2}/" /home/user1/file1.txt

Below is the shell script file content:

#!/bin/bash

string1="The quick brown fox jumps over the lazy fat dog"

string2="The quick little black fox jumps over the lazy fat dog
The quick big brown fox jumps over the lazy fat dog
The lazy little brown fox jumps over the lazy fat dog"

sed -i "s/$string1/$string2/" /home/user1/file1.txt

#sed -i "/${string1}/{s/^.*/${string2}/" /home/user1/file1.txt
6
  • 1
    There should be no / before s command, sed -i "s/$string1/$string2/" /home/user1/file1.txt Commented Jun 15, 2020 at 21:39
  • 1
    Though sed is generally a poor choice of tools for this job -- one needs to do escaping or else not all characters will work correctly (/, in the case of Wiktor's example above). See BashFAQ #21, and particularly the definition of gsub_literal therein, for tools that do it better. (There's also a perl-based alternative described in that same page). Commented Jun 15, 2020 at 21:45
  • @WiktorStribiżew, apologies, that was a typo. Commented Jun 15, 2020 at 21:47
  • @CharlesDuffy I just added the none as per your advice to make the block a literal data. Thanks. Commented Jun 15, 2020 at 21:52
  • 1
    gsub_literal is built on awk. Being POSIX-defined, that's more likely to be present. Commented Jun 15, 2020 at 21:56

2 Answers 2

1

replace a line content in a file with multiple lines

In sed commands are delimetered with a newline. So when sed sees s/blabla/blabla<newline> is parses that part as a full command and exits with a missing closing /.

You can substitute each newline in the replacement string for two characters \n, which can be then substituted by sed for a newline once again.

string2=${string2//$'\n'/\\n}
sed "s/$string1/$string2/"

Note that sed parses first part of s command as a regex and in replacement string some strings (\1 & \L \U etc.) are also parsed specially.

This will only work if there are no newlines in string1. With GNU sed you can get away with newlines in string1 by using -z option, that will cause to parse the input as zero terminated strings.

Sign up to request clarification or add additional context in comments.

Comments

1

This might work for you (GNU sed):

echo "$string2" | sed "s/$string1/cat -/e" file

This uses the e flag in the substitution command to send $string2 to stdout using the stdin from the echoed pipe.

It should be noted $string1 must be a single line and not contain any meta characters. If $string1 does contains special characters, this might work in bash:

echo "$string2" |
sed 's/'"$(<<<"$string3" sed 's/[][^$.*&\/]/\\&/g')"'/cat -/e' file

This escapes any meta characters in $string1 which then becomes the LHS of the substitution regexp.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.