Strip last part of file by pattern - remove last certificate from chain

888 views Asked by At

I have a chain of SSL certificates like this

-----BEGIN CERTIFICATE-----
MIICPjCCAeSgAwIBAgIRALMMpKnhRM2C7mnKI/rl8ggwCgYIKoZIzj0EAwIwgY4x
CERT1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIjCCAsegAwIBAgIOAMjnPM1wShDmOWUELuIwCgYIKoZIzj0EAwIwgagxCzAJ
CERT2
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIDCCAsWgAwIBAgIOAMjnPL8JUbVSmpMadWUwCgYIKoZIzj0EAwIwbDELMAkG
CERT3
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDBjCCAqygAwIBAgIFFRCCEwYwCgYIKoZIzj0EAwIwgZQxFDASBgNVBAoMC0Ft
CERT4
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDNjCCAtugAwIBAgIJAKpBxYNyH8biMAoGCCqGSM49BAMCMIGUMRQwEgYDVQQK
CERT5
-----END CERTIFICATE-----

and I need to strip the last certificate from it.

On MacOS/BSD command split has flag -p to split by pattern, and I used it:

cat cert | split -p "-----BEGIN CERTIFICATE-----" 
cat xa{a,b,c,d}

I believe there is a command to do it in one line on Linux too, but on Ubuntu the command split is not able to split by pattern.

I need to do the job using standard linux commands, such as those I tagged.

3

There are 3 answers

6
Enlico On BEST ANSWER

This GNU Sed solution should be enough:

sed -zE 's/(.*\n)-----BEGIN CERTIFICATE-----.*/\1/' your_input
  • -E allows one to use (…) instead of \(…\) to capture something;
  • -z (available in GNU Sed) is to treat the whole input as a single long string with embedded \ns.

Therefore, the first .* matches as much as it can (and captures it, together with the \n right after it, so it can reference it in the substitution by using \1), as long as it is followed by \n-----BEGIN CERTIFICATE----- and anything else after it (the second .*).

3
RavinderSingh13 On

With GNU awk using gensub you could try following, written and tested based on shown samples only.

awk -v RS="" -v regex="(.*)\n(-----BEGIN CERTIFICATE-----.*)" '
{
  print gensub(regex,"\\1","1",$0)
}' Input_file
4
Ed Morton On

With any awk alone:

$ awk '/-----BEGIN CERTIFICATE-----/{printf "%s", rec; rec=""} {rec=rec $0 ORS}' file
-----BEGIN CERTIFICATE-----
MIICPjCCAeSgAwIBAgIRALMMpKnhRM2C7mnKI/rl8ggwCgYIKoZIzj0EAwIwgY4x
CERT1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIjCCAsegAwIBAgIOAMjnPM1wShDmOWUELuIwCgYIKoZIzj0EAwIwgagxCzAJ
CERT2
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIDCCAsWgAwIBAgIOAMjnPL8JUbVSmpMadWUwCgYIKoZIzj0EAwIwbDELMAkG
CERT3
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDBjCCAqygAwIBAgIFFRCCEwYwCgYIKoZIzj0EAwIwgZQxFDASBgNVBAoMC0Ft
CERT4
-----END CERTIFICATE-----

or if you have tac:

$ tac file | awk 'f; /-----BEGIN CERTIFICATE-----/{f=1}' | tac
-----BEGIN CERTIFICATE-----
MIICPjCCAeSgAwIBAgIRALMMpKnhRM2C7mnKI/rl8ggwCgYIKoZIzj0EAwIwgY4x
CERT1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIjCCAsegAwIBAgIOAMjnPM1wShDmOWUELuIwCgYIKoZIzj0EAwIwgagxCzAJ
CERT2
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIDCCAsWgAwIBAgIOAMjnPL8JUbVSmpMadWUwCgYIKoZIzj0EAwIwbDELMAkG
CERT3
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDBjCCAqygAwIBAgIFFRCCEwYwCgYIKoZIzj0EAwIwgZQxFDASBgNVBAoMC0Ft
CERT4
-----END CERTIFICATE-----