我有一个包含结构化数据的字符串(请参见下文)。我需要使用此字符串并将其转换为对象,以便可以将其导出到.csv(或其他要求我执行的操作)。我运行了以下代码:
$data = $string -replace "\s*:\s*","="
但是我的输出看起来像这样:
City=Country=Department=DisplayName=John Doe
DistinguishedName=CN=John Doe, CN=Users, DC=domain, DC=com
EmailAddress=jdoe@domain.com
Enabled=False
Fax=GivenName=John
MobilePhone=Name=John Doe
ObjectClass=user
ObjectGUID=cdb9a45c-80f4-4919-bf43-5db8d9ca83da
Office=OfficePhone=PostalCode=SamAccountName=jdoe
SID=S-1-5-21-2025429266-2000478354-1606980848-16934
State=StreetAddress=Surname=Doe
Title=UserPrincipalName=jdoe@domain.com
这显然是不正确的。什么是进行此转换的更好方法?我曾考虑过将ConvertFrom-String与TemplateContent参数一起使用,但还无法使之工作。
这是字符串中的前两个条目(其中包含多个用户的数据):
$string = @"
City :
Country :
Department :
DisplayName : John Doe
DistinguishedName : CN=John Doe,CN=Users,DC=domain,DC=com
EmailAddress : jdoe@domain.com
Enabled : False
Fax :
GivenName : John
MobilePhone :
Name : John Doe
ObjectClass : user
ObjectGUID : cdb9a45c-80f4-4919-bf43-5db8d9ca83da
Office :
OfficePhone :
PostalCode :
SamAccountName : jdoe
SID : S-1-5-21-2025429266-2000478354-1606980848-16934
State :
StreetAddress :
Surname : Doe
Title :
UserPrincipalName : jdoe@domain.com
City :
Country :
Department :
DisplayName : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}
DistinguishedName : CN=DiscoverySearchMailbox {D919BA15-46A6-415f-80AD-7E09334BB852},CN=Users,DC=domain,DC=com
EmailAddress : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}@domain.com
Enabled : False
Fax :
GivenName :
MobilePhone :
Name : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}
ObjectClass : user
ObjectGUID : 0f35137a-de93-472f-9114-5488a462d178
Office :
OfficePhone :
PostalCode :
SamAccountName : SM_2187102a90634829b
SID : S-1-5-21-2438891277-1009865731-3229889747-3109
State :
StreetAddress :
Surname : MsExchDiscoveryMailbox D919BA15-46A6-415f-80AD-7E09334BB852
Title :
UserPrincipalName : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}@domain.com
"@
谢谢。
答案 0 :(得分:2)
如果:
:
的值Select-Object
调用来显式枚举属性), 您可以使用ConvertFrom-StringData
(我建议避免使用挑剔且文献记录不充分的ConvertFrom-String
)
$string.Trim() -split '(?m)(?=^City\b)' -ne '' | ForEach-Object {
[pscustomobject] ($_ -replace ':', '=' | ConvertFrom-StringData)
} # | Export-Csv ....
注意:投射到[pscustomobject]
需要PSv3 +;在PSv2上,使用New-Object PSCustomObject -Property (...)
$string.Trim() -split '(?m)(?=^City\b)' -ne ''
将输入行分成行块,每行代表一个对象;拆分由以City
开头的行执行; -ne ''
滤除解析输入开始时产生的空白块。
.Trim()
需要忽略字符串开头的空行。 $_ -replace ':', '=' | ConvertFrom-StringData
将每个块转换为
<key>=<value>
行中ConvertFrom-StringData
行转换为[hashtable]
实例的[pscustomobject]
行;因为哈希表固有地以没有保证的顺序枚举其条目,所以这就是属性的输入顺序丢失的地方。
Cast Export-Csv
将每个哈希表转换为隐式输出的自定义对象;输出可以通过管道传递到match goal with
| [ e : expr, H : (is_v_of_expr e = true) |- _ ] => idtac
end.
(* The reference e was not found in the current environment *)
。
答案 1 :(得分:0)
转义序列\s
与所有空格匹配,包括换行符。因此,没有值的行实际上与下一行合并。在换行符处分割字符串,进行替换,然后将字符串数组合并回单个字符串。
$data = $string -split '\r?\n' -replace '\s*:\s*','=' | Out-String
或确保您不替换换行符:
$data = $string -replace '[\t ]*:[\t ]*', '='
编辑:
由于输入数据似乎由多个记录组成,而不仅仅是一个记录,因此您需要按记录对结果字符串进行拆分,以便每个数据集具有单独的字符串。使用ConvertFrom-StringData
将每个数据集转换为哈希表,然后将这些哈希表转换为自定义对象。
$data = $string -split '(?<=\r?\n)\r?\n' | ForEach-Object {
$prop = $_.Trim() -split '\r?\n' -replace '\s*:\s*','=' |
Out-String |
ConvertFrom-StringData
New-Object -Type PSObject -Property $prop
}
在PowerShell v3和更高版本中,您可以使用[PSCustomObject]
类型的加速器来代替New-Object
:
$data = $string -split '(?<=\r?\n)\r?\n' | ForEach-Object {
$prop = $_.Trim() -split '\r?\n' -replace '\s*:\s*','=' |
Out-String |
ConvertFrom-StringData
[PSCustomObject]$prop
}
然后可以将结果对象列表导出为CSV。
答案 2 :(得分:0)
您在这里:)
Gucci
结果对象看起来像这样
$a=@"
City :
Country :
Department :
DisplayName : John Doe
DistinguishedName : CN=John Doe,CN=Users,DC=domain,DC=com
EmailAddress : jdoe@domain.com
Enabled : False
Fax :
GivenName : John
MobilePhone :
Name : John Doe
ObjectClass : user
ObjectGUID : cdb9a45c-80f4-4919-bf43-5db8d9ca83da
Office :
OfficePhone :
PostalCode :
SamAccountName : jdoe
SID : S-1-5-21-2025429266-2000478354-1606980848-16934
State :
StreetAddress :
Surname : Doe
Title :
UserPrincipalName : jdoe@domain.com
"@
$b=ConvertFrom-Csv -InputObject $a -Delimiter ':' -Header "key","value"
$c=New-Object -TypeName System.Management.Automation.PSObject
$b|%{ $c|Add-Member -NotePropertyName $_.key -NotePropertyValue "$($_.value)"}
如果这种解决方案似乎是一个好主意,我将继续研究我的答案。
显然,它需要去除空格和一些更好的变量名,但是我相信您可以自己完成:)