regex 使用Powershell提取PEM文件行,在开头和结尾添加引号,使其成为一行

qmb5sa22  于 2023-10-22  发布在  Shell
关注(0)|答案(1)|浏览(179)

如何获取.PEM的内容,如下所示:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ6AMIIBCgKCAQEAse68c1suNUQr0d79VudK
XgmNxggQoaqR9fZoCrUz/gRS5XZm9wDL9HHxjYjEhZsuXQw1SZpYggjRQuqE+7Nx
mhgn6DXXjWiTZ2b/ScE9mu+RQyh4hWEk9u+uUD2MZ9oPUZi2tN43InH9Qduza1Fe
jQeh6OW6Bg+fTsBXtPJWawF/3oMCdWVfZ8Iel0ilP+61B5ldkw7g//QMf5mqzvkQ
HK5/gKPCfGUylRDtJOxOriM5XqCjgtw6Sye8hgql5DGOCZTrXAahNbnw0bGm5TYW
qosD+B2Rh/Xa600j/X0JAABQ8Pi1b0PAycGdMW7HPQ1YAp5Q7PbQQxlmlWeHQEgO
wwIDAQAB
-----END PUBLIC KEY-----

让它看起来像这样的一行:

"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ6AMIIBCgKCAQEAse68c1suNUQr0d79VudK" "XgmNxggQoaqR9fZoCrUz/gRS5XZm9wDL9HHxjYjEhZsuXQw1SZpYggjRQuqE+7Nx" "mhgn6DXXjWiTZ2b/ScE9mu+RQyh4hWEk9u+uUD2MZ9oPUZi2tN43InH9Qduza1Fe" "jQeh6OW6Bg+fTsBXtPJWawF/3oMCdWVfZ8Iel0ilP+61B5ldkw7g//QMf5mqzvkQ" "HK5/gKPCfGUylRDtJOxOriM5XqCjgtw6Sye8hgql5DGOCZTrXAahNbnw0bGm5TYW" "qosD+B2Rh/Xa600j/X0JAABQ8Pi1b0PAycGdMW7HPQ1YAp5Q7PbQQxlmlWeHQEgO" "bwIDAQAB"

我可以使用以下命令删除开始和结束行:

$File = "C:\pathto\some.pem"
    $content = Get-Content $file
    $contents =  $content
    
    $Complete = [regex]::split($contents, "-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----")
    
    for($i = 1; $i -lt $Complete.Length; $i =$i+2){
        $Complete[$i] -replace " ","`r`n"
    }
v1uwarro

v1uwarro1#

首先,一些警告:

  • 正如注解中所指出的,预期输出中的引号似乎不匹配-字符串开头的引号("k=rsa)被第一个p值结尾的引号(p=MIIB...VudK")关闭。我不确定这是一个错别字还是预期的输出,所以我将从表面上看,并假设这是预期的输出。如果这是一个错字,你可能需要稍微调整一下这个答案。
  • 同样,问题中PEM data 的最后一行是wwIDAQAB,但您的示例输出以"bwIDAQAB"结束-一个以w开始,另一个以b开始-我将假设这是一个错字,我将使用以b开始的值来匹配预期的输出。

回答

Get-Content返回一个字符串的 array,它等价于:

$content = @(
    "-----BEGIN PUBLIC KEY-----",
    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ6AMIIBCgKCAQEAse68c1suNUQr0d79VudK",
    "XgmNxggQoaqR9fZoCrUz/gRS5XZm9wDL9HHxjYjEhZsuXQw1SZpYggjRQuqE+7Nx",
    "mhgn6DXXjWiTZ2b/ScE9mu+RQyh4hWEk9u+uUD2MZ9oPUZi2tN43InH9Qduza1Fe",
    "jQeh6OW6Bg+fTsBXtPJWawF/3oMCdWVfZ8Iel0ilP+61B5ldkw7g//QMf5mqzvkQ",
    "HK5/gKPCfGUylRDtJOxOriM5XqCjgtw6Sye8hgql5DGOCZTrXAahNbnw0bGm5TYW",
    "qosD+B2Rh/Xa600j/X0JAABQ8Pi1b0PAycGdMW7HPQ1YAp5Q7PbQQxlmlWeHQEgO",
    "bwIDAQAB",
    "-----END PUBLIC KEY-----"
);

(note我已经将最后一行数据改为bwIDAQAB,以匹配您的预期输出)。
为了完整起见,这里是您的预期输出:

$expected = '"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ6AMIIBCgKCAQEAse68c1suNUQr0d79VudK" "XgmNxggQoaqR9fZoCrUz/gRS5XZm9wDL9HHxjYjEhZsuXQw1SZpYggjRQuqE+7Nx" "mhgn6DXXjWiTZ2b/ScE9mu+RQyh4hWEk9u+uUD2MZ9oPUZi2tN43InH9Qduza1Fe" "jQeh6OW6Bg+fTsBXtPJWawF/3oMCdWVfZ8Iel0ilP+61B5ldkw7g//QMf5mqzvkQ" "HK5/gKPCfGUylRDtJOxOriM5XqCjgtw6Sye8hgql5DGOCZTrXAahNbnw0bGm5TYW" "qosD+B2Rh/Xa600j/X0JAABQ8Pi1b0PAycGdMW7HPQ1YAp5Q7PbQQxlmlWeHQEgO" "bwIDAQAB"'

这段代码将完成您所追求的(带有上述警告):

$complete = @(
    "`"k=rsa; p=",
    ($content[1..($content.Length - 2)] -join "`" `""),
    "`""
) -join ""

$complete -eq $expected
# True

基本上是:

  • "k=rsa; p=前缀开头
  • 丢弃PEM输入的第一行和最后一行
  • 用文本" "分隔符连接其余的行
  • 添加"后缀

给予:

"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ6AMIIBCgKCAQEAse68c1suNUQr0d79VudK" "XgmNxggQoaqR9fZoCrUz/gRS5XZm9wDL9HHxjYjEhZsuXQw1SZpYggjRQuqE+7Nx" "mhgn6DXXjWiTZ2b/ScE9mu+RQyh4hWEk9u+uUD2MZ9oPUZi2tN43InH9Qduza1Fe" "jQeh6OW6Bg+fTsBXtPJWawF/3oMCdWVfZ8Iel0ilP+61B5ldkw7g//QMf5mqzvkQ" "HK5/gKPCfGUylRDtJOxOriM5XqCjgtw6Sye8hgql5DGOCZTrXAahNbnw0bGm5TYW" "qosD+B2Rh/Xa600j/X0JAABQ8Pi1b0PAycGdMW7HPQ1YAp5Q7PbQQxlmlWeHQEgO" "bwIDAQAB"

如果你不喜欢使用范围运算符(..),你可以用select-object来代替:

$complete = @(
    "`"k=rsa; p=",
    (($content | select-object -Skip 1 -First ($content.Length - 2)) -join "`" `""),
    "`""
) -join ""

$complete -eq $expected
# True

这是一种稍微冗长的方式来做同样的事情。

奖励内容

您的线路:

$Complete = [regex]::split($contents, "-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----")

将字符串的$contentsarray 强制转换为单个字符串,因为这是[regex]::Split所期望的,如果在PowerShell会话中执行[regex]::Split,您可以看到:

PS> [regex]::Split

OverloadDefinitions
-------------------
static string[] Split(string input, string pattern)
static string[] Split(string input, string pattern, System.Text.RegularExpressions.RegexOptions options)
static string[] Split(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, timespan matchTimeout)

所有三个重载中的第一个参数都是string input
PowerShell中的默认行为是,在对值数组进行字符串化时,使用空格分隔符连接它们的.ToString()结果。例如

PS> "$content"
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ6AMIIBCgKCAQEAse68c1suNUQr0d79VudK XgmNxggQoaqR9fZoCrUz/gRS5XZm9wDL9HHxjYjEhZsuXQw1SZpYggjRQuqE+7Nx mhgn6DXXjWiTZ2b/ScE9mu+RQyh4hWEk9u+uUD2MZ9oPUZi2tN43InH9Qduza1Fe jQeh6OW6Bg+fTsBXtPJWawF/3oMCdWVfZ8Iel0ilP+61B5ldkw7g//QMf5mqzvkQ HK5/gKPCfGUylRDtJOxOriM5XqCjgtw6Sye8hgql5DGOCZTrXAahNbnw0bGm5TYW qosD+B2Rh/Xa600j/X0JAABQ8Pi1b0PAycGdMW7HPQ1YAp5Q7PbQQxlmlWeHQEgO bwIDAQAB -----END PUBLIC KEY-----

这就是你传递到正则表达式中的内容,如果你想知道的话:-).

相关问题