简体   繁体   English

按模式剥离文件的最后一部分 - 从链中删除最后一个证书

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

I have a chain of SSL certificates like this我有一个像这样的 SSL 证书链

-----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:在 MacOS/BSD 命令split有标志-p按模式拆分,我使用它:

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.我相信在 Linux 上也有一个命令可以在一行中完成,但在 Ubuntu 上,命令split无法按模式拆分。

I need to do the job using standard linux commands, such as those I tagged.我需要使用标准的 linux 命令来完成这项工作,比如我标记的那些。

This GNU Sed solution should be enough这个 GNU Sed 解决方案应该足够了

sed -zE 's/(.*\n)-----BEGIN CERTIFICATE-----.*/\1/' your_input

where -E allows one to use (…) instead of \\(…\\) to capture something, and -z (available in GNU Sed) is to treat the whole input as a single long string with embedded \\n s.其中-E允许使用(…)而不是\\(…\\)来捕获某些内容,而-z (在 GNU Sed 中可用)将整个输入视为带有嵌入\\n的单个长字符串。

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 .* ).因此,第一.*比赛一样,因为它可以(并捕获它,连同\\n之后,因此它可以通过使用引用它在置换\\1 ),只要它后面是\\n-----BEGIN CERTIFICATE-----以及它之后的任何其他内容(第二个.* )。

With any awk alone:单独使用任何 awk:

$ 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

$ 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-----

With GNU awk using gensub you could try following, written and tested based on shown samples only.使用使用gensub GNU awk您可以尝试仅基于显示的示例进行跟踪、编写和测试。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM