How to replace text between two patterns on different lines?

Solution 1:

It should work for you:

sed -e '/Security-Start/{ N; s/Security-Start.*Security-End/REDACTED/ }'
  • /Security-Start/ search for "Security-Start"
  • If you found it: "N;" means append the next line.
  • and do the replacements/Security-Start.*Security-End/REDACTED/ at the final result.

For more than of two line use this one:

sed -n '1h; 1!H; ${ g; s/Security-Start.*Security-End/REDACTED/p }'

Read here

Solution 2:

If the files are not too large, then you could use perl in slurp mode:

$ perl -0777 -pe 's/Security-Start.*Security-End/REDACTED/s' file 
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

The -0777 command line parameter effectively unsets the record separator so that the whole file is slurped. The s regex modifier causes perl to include newline characters in ., making the expression match across lines.


Alternatively, with a sed loop:

$ sed '/Security-Start/ {:a; $!N; s/Security-Start.*Security-End/REDACTED/; t; ba}' file
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

With GNU sed, you can replace t; ba (branch out on successful replacement; (otherwise) branch to :a) by Ta (branch to :a on unsuccessful replacement).