首页 > 解决方案 > 使用 Powershell 和正则表达式将字符串解析为自定义对象

问题描述

我有一个字符串,我尝试将其解析为带有子表达式的 PSCustom 对象数组。

字符串看起来像这样:

date=2021-09-13 time=20:05:25 devname="chwitrfg01" devid="FG10E0TB20903187" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1631556325 srcip=192.168.10.226 srcname="192.168.10.226" srcport=54809 srcintf="port8" srcintfrole="dmz" dstip=8.8.4.4 dstname="dns.google" dstport=53 dstintf="wan1" dstintfrole="lan" poluuid="01533038-da7b-51eb-b854-8fd38a0deba3" sessionid=1472996904 proto=17 action="accept" policyid=278 policytype="policy" service="DNS" dstcountry="United States" srccountry="Reserved" trandisp="snat" transip=194.56.218.226 transport=54809 duration=180 sentbyte=245 rcvdbyte=144 sentpkt=2 rcvdpkt=1 shapersentname="default_class" shaperdropsentbyte=0 shaperrcvdname="default_class" shaperdroprcvdbyte=0 appcat="unscanned" dstdevtype="Unknown" dstdevcategory="None" masterdstmac="00:00:0c:07:ac:8d" dstmac="00:00:0c:07:ac:8d" dstserver=1

我尝试过这样的事情,但我是正则表达式的菜鸟,不知道如何解决这个问题。有没有一种简单的方法可以将每个值添加到自定义对象的属性中?

$Pattern = @(
    '(?<devname>\devname=w+)'
    '(?<srcip>(srcip=?:[0-9]+\.){3}[0-9]+):(?<srcport>srcport=[0-9]+)'
    '(?<dstip>(dstip=?:[0-9]+\.){3}[0-9]+):(?<dstport>dstport=[0-9]+)'
    
) -join '\s+'

$cmd |
    ForEach-Object {
    if ($_ -match $Pattern) {
    $Matches.Remove(0)
        [PsCustomObject]@{
            srcip = $_.Groups['srcip'].Value
            dstip = $_.Groups['dstip'].Value
            dstport = $_.Groups['dstport'].Value
            srcport = $_.Groups['srcport'].Value
            fw = $_.Groups['devname'].Value
        }
      }
    }| Select-Object -First 5
$cmd  | Format-Table

标签: regexpowershell

解决方案


我知道的最简单的方法是ConvertFrom-StringDatacmdlet。name=value该 cmdlet 从一组格式化的事物中创建名称/值对的哈希表。您要做的是将每个值放在自己的行上以创建一个多字符串,然后创建一个新的自定义对象,并使用该哈希表来定义属性。

$cmd -replace ' (\w+=)',"`n`$1"|
    %{new-object psobject -prop (ConvertFrom-StringData $_)}

或 v3+ 中的较短版本(感谢 @mklement0):

$cmd -replace ' (\w+=)',"`n`$1"|
    %{[pscustomobject] (ConvertFrom-StringData $_)}

当我对你提供的字符串运行它时,我回来了:

sessionid          : 1472996904
action             : "accept"
rcvdbyte           : 144
vd                 : "root"
logid              : "0000000013"
policyid           : 278
duration           : 180
proto              : 17
dstname            : "dns.google"
srcintf            : "port8"
eventtime          : 1631556325
appcat             : "unscanned"
srcip              : 192.168.10.226
dstip              : 8.8.4.4
trandisp           : "snat"
srcname            : "192.168.10.226"
srcport            : 54809
devid              : "FG10E0TB20903187"
dstdevcategory     : "None"
level              : "notice"
sentbyte           : 245
shaperdroprcvdbyte : 0
sentpkt            : 2
masterdstmac       : "00:00:0c:07:ac:8d"
shaperrcvdname     : "default_class"
poluuid            : "01533038-da7b-51eb-b854-8fd38a0deba3"
type               : "traffic"
srcintfrole        : "dmz"
subtype            : "forward"
policytype         : "policy"
dstport            : 53
transip            : 194.56.218.226
shapersentname     : "default_class"
dstdevtype         : "Unknown"
dstserver          : 1
dstcountry         : "United States"
dstintf            : "wan1"
service            : "DNS"
srccountry         : "Reserved"
shaperdropsentbyte : 0
dstintfrole        : "lan"
transport          : 54809
date               : 2021-09-13
rcvdpkt            : 1
dstmac             : "00:00:0c:07:ac:8d"
devname            : "chwitrfg01"
time               : 20:05:25

如果需要,您可能可以从中删除引号。


推荐阅读