首页 > 解决方案 > 使用以 some-pattern 开头并以 other-pattern 结尾的搜索模式过滤 powershell 输出

问题描述

我受到 bash 命令行的启发,其中sed输出以“-BEGIN CERTIFICATE-”开头并以“-END CERTIFICATE-”结尾的搜索模式

openssl s_client -connect www.domain.com:443 -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

我如何获得过滤器以便它在powershell中工作,可能与Select-String

这是 bash 命令的输出:

$ openssl s_client -connect google.com:443 -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

-----BEGIN CERTIFICATE-----
MIIJVzCCCD+gAwIBAgIRANFJW61SRurECAAAAABTHOIwDQYJKoZIhvcNAQELBQAw
...cut...
jPCWTiAulvBLJJQ9nmggAgaEg7/9bs6da47V5awlyEAKzzmHGAmcNpX71Q==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw
...cut...
USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==
-----END CERTIFICATE-----

共77行

标签: powershell

解决方案


没有什么比 内置的更简洁了sed,但我经常发现该switch语句对于使用正则表达式逐行解析多行输出很有用:

# flag to keep track of whether we're between BEGIN/END
$inCert = $false

# suppress stderr output from openssl, assign all output from switch to `$certs`
$certs = switch -Regex ("`n`n"|openssl s_client -connect google.com:443 -showcerts 2>$null){
  '-BEGIN CERTIFICATE-' {
    # alright, we encountered a BEGIN line, prepare to consume following lines as a cert
    $partialCert = @()
    $inCert = $true
  }
  '-END CERTIFICATE-' {
    # reach END, output the current certificate
    $inCert = $false
    $partialCert -join [System.Environment]::NewLine
  }
  default {
    # ignore anything as long as we're not in between BEGIN/END
    if($inCert){
      $partialCert += $_
    }
  }
}

# $certs now contain the base64-encoded certificates 

推荐阅读