sedpattern-matchingmultiline

using sed to replace multiline pattern by contents of file


I have a file certs.txtcontaining sections with multiline patterns such as

  CAChain = [IIH1zCCBr+gAwIBAgISBPW9KTc3ma4BJ5Dwjsap3vuSMA0GCSqGSIb3DQEBCwUAMDMxCzAJ
BgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQDEwNSMTEwHhcNMjQw
OTE4MDE0MjE5WhcNMjQxMjE3MDE0MjE4WjAWMRQwEgYDVQQDEwt3ZXJrd2VsdC5kZTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ09pgyz+iRHeuckR92soEwaN7/WzGIigdQV
...
...
x3bn
];

Each section can be identified by sed "s/= \[[^\]]*\];/= [/" but my search doesn't cross lines.

Aim is to replace

CAChain = [IIH1zCCBr+gAwIBAgISBPW9KTc3ma4BJ5Dwjsap3vuSMA0GCSqGSIb3DQEBCwUAMDMxCzAJ
BgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQDEwNSMTEwHhcNMjQw
OTE4MDE0MjE5WhcNMjQxMjE3MDE0MjE4WjAWMRQwEgYDVQQDEwt3ZXJrd2VsdC5kZTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ09pgyz+iRHeuckR92soEwaN7/WzGIigdQV
...
...
x3bn];

by

CAChain = [ <contents of file> 
];

Solution

  • This might work for you (GNU sed):

    sed -E '/= \[/{:a;N;/\];/!ba
            s/(= \[).*(\];)/\1$(cat replacementFile)\2/
            s/.*/echo "&"/e}' file
    

    Search for the start of a section then gather up further lines until the end of the section.

    Using the substitution command replace inside the square brackets with a shell command to cat the entire replacement file.

    Using the substitution command and the e flag replace the entire contents of the pattern space by an echo command which when evaluated will output the required result.