How to replace a multi line code with sed?

Perl to the rescue:

perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
  • -i~ will edit the file "in place", leaving a backup copy
  • -0777 reads the whole file at once, not line by line

The substitution s/// works similarly as in sed (i.e. it matches text = " followed by anything but double quotes many times up to a double quote), but in this case, it works on the whole file.


You have to check the pattern space and keep pulling in the Next line if it doesn't match e.g.

sed '/text = "/{              # if line matches text = "
:b                            # label b
$!N                           # pull in the next line (if not the last one)
/"$/!bb                       # if pattern space doesn't end with " go to label b
s/".*"/""/                    # else remove everything between the quotes
}' infile

with gnu sed you can write it as

sed '/text = "/{:b;$!N;/"$/!bb;s/".*"/""/}' infile

That's not very efficient though, better just select the range /text = "/,/"/, modify the first line and delete the rest:

sed '/text = "/,/"/{            # in this range
/text = "/!d                    # delete all lines not matching text = "
s/\\/"/                         # replace the backslash with quotes (this is only
}' infile                       # executed if the previous d wasn't executed)

again, with gnu sed you can write it as a one-liner:

sed '/text = "/,/"/{/text = "/!d;s/\\/"/}' infile

Personally, I would do this in Perl. If we can assume that there are no " before the closing ", you can do:

perl -0pe 's/(text\s*=\s*)".*?"/$1""/s' file

The -0 slurps the entire file, reading it into memory. The -p means "print every line (here, a "line" will be the entire file) after applying the script given by -e". The script itself is a simple substitution operator. It will capture the string text followed by 0 or more whitespace characters, an = and 0 or more whitespace again (text\s*=\s*) and save it as $1. Then, it will replace the captured pattern as well as the shortest quoted string it finds with the pattern ($1) and "". The s flag makes . match newlines.