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 N
ext 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.