我正在嘗試在加載 CSV 時進行一些檢查,并通知用戶發現了哪些額外的標頭以及哪些仍然缺失。$headers_required 將被硬編碼, $headers_loaded 將由 Import-CSV 填充目標是使用與另一個陣列的差異填充兩個陣列,如 Unix 中的 diff 。
$headers_required=@( `
'Path', `
'GivenName', `
'Name', `
'EmailAddress', `
'sAMAccountName', `
'psw-temp', `
'Path', `
'ChangePasswordAtLogon' `
)
$headers_loaded=@( `
'Path', `
'GivenName', `
'Name', `
'PhoneNumber', `
'PreferredFilm', `
'sAMAccountName', `
'psw-temp', `
'Path', `
'ChangePasswordAtLogon', `
'BankAccount' `
)
最終我想擁有
$extra_headers_not_nedeed=@('BankAccount', 'PhoneNumber', 'PreferredFilm')
$missing_headers=@('EmailAddress')
我可以用這種方式過濾它們
$extra_headers_not_nedeed=Compare-Object ($headers_required|Sort-Object) ($headers_loaded|Sort-Object) | Where SideIndicator -eq '<='
$missing_headers=Compare-Object ($headers_required|Sort-Object) ($headers_loaded|Sort-Object) | Where SideIndicator -eq '=>'
我確實過濾了它們
PS C:\> $missing_headers|Write-host
@{InputObject=EmailAddress; SideIndicator=<=}
PS C:\> $extra_headers_not_needed|Write-host
@{InputObject=BankAccount; SideIndicator==>}
@{InputObject=PhoneNumber; SideIndicator==>}
@{InputObject=PreferedFilm; SideIndicator==>}
如何獲得上面指定的普通陣列而不是結構化物件?我試過 $missing_headers['InputObject'] 但它回傳整個物件而不是 'EnailAddress'
有沒有更緊湊的方式(除了符號)來獲得相同的結果?
TIA
uj5u.com熱心網友回復:
我會使用一個function你可以重用的,并且可以動態分配新的參考頭來與你的 Csv 進行比較。
我不會Compare-Object個人使用,我認為它會帶走所有的樂趣。
function Test-Csv {
param(
[parameter(mandatory)]
[string[]]$ReferenceHeaders,
[parameter(mandatory)]
[object]$InputObject
)
$csvHeaders = $InputObject[0].PSObject.Properties.Name
$valid, $missing = $ReferenceHeaders.where({ $_ -in $csvHeaders }, 'Split')
$invalid = $csvHeaders.where({ $_ -notin $ReferenceHeaders })
$valid.foreach({
[pscustomobject]@{
HeaderName = $_
Status = 'Valid'
}
})
$missing.foreach({
[pscustomobject]@{
HeaderName = $_
Status = 'Missing'
}
})
$invalid.foreach({
[pscustomobject]@{
HeaderName = $_
Status = 'Invalid'
}
})
}
用法
# Define the Reference Headers
$requiredHeaders =@(
'Path'
'GivenName'
'Name'
'EmailAddress'
'sAMAccountName'
'psw-temp'
'ChangePasswordAtLogon'
)
# This example Csv would be the one you import from a file as an example
$exampleCsv = @'
GivenName,sAMAccountName,RandomHeader1,Path,RandomHeader2
z,z,z,z,z
'@ | ConvertFrom-Csv
PS \> Test-Csv -ReferenceHeaders $requiredHeaders -InputObject $exampleCsv
HeaderName Status
---------- ------
Path Valid
GivenName Valid
sAMAccountName Valid
Name Missing
EmailAddress Missing
psw-temp Missing
ChangePasswordAtLogon Missing
RandomHeader1 Invalid
RandomHeader2 Invalid
PS \> $result = Test-Csv -ReferenceHeaders $requiredHeaders -InputObject $exampleCsv
PS \> $result | Where-Object Status -EQ 'Missing'
HeaderName Status
---------- ------
Name Missing
EmailAddress Missing
psw-temp Missing
ChangePasswordAtLogon Missing
PS \> $result | Where-Object Status -EQ 'Invalid'
HeaderName Status
---------- ------
RandomHeader1 Invalid
RandomHeader2 Invalid
uj5u.com熱心網友回復:
將-PassThru引數添加到compare-object命令中:
# ~> $extra_headers_not_nedeed=Compare-Object ($headers_required|Sort-Object) ($headers_loaded|Sort-Object) -passthru| Where SideIndicator -eq '<='
# ~> $extra_headers_not_nedeed
EmailAddress
# ~> $missing_headers=Compare-Object ($headers_required|Sort-Object) ($headers_loaded|Sort-Object) -PassThru | Where SideIndicator -eq '=>'
# ~> $missing_headers
BankAccount
PhoneNumber
PreferredFilm
uj5u.com熱心網友回復:
只是另一種選擇:
Clear-Host
$Extra_Headers_Not_Needed = New-Object -TypeName 'System.Collections.ArrayList'
$Missing_Headers = New-Object -TypeName 'System.Collections.ArrayList'
$x = Compare-Object ($headers_required|Sort-Object) ($headers_loaded|Sort-Object)
ForEach ( $header in $x) {
Switch (($Header).SideIndicator) {
'=>' {$Null = $Extra_Headers_Not_Needed.Add($Header.InputObject) ; Break}
'<=' {$Null = $Missing_Headers.Add($Header.InputObject) ; Break}
Default {"Error: $($Header.InputObject)" }
}
}
"Not Needed $($Extra_Headers_Not_Needed.Count) :"
$Extra_Headers_Not_Needed
"`nMissing Headers $($Missing_Headers.Count) :"
$Missing_Headers
輸出:
Not Needed 3 :
BankAccount
PhoneNumber
PreferredFilm
Missing Headers 1 :
EmailAddress
uj5u.com熱心網友回復:
感謝茲丹和圣地亞哥,
最終我也找到了這種方式(來自 a[key]='value' 概念)
PS C:\> $missing_headers.'InputObject'
BankAccount
PhoneNumber
PreferredFilm
PS C:\> $extra_headers_not_nedeed.'InputObject'
EmailAddress
因為
PS C:> $extra_headers_not_nedeed.psobject.properties
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : EmailAddress
TypeNameOfValue : System.String
Name : InputObject
IsInstance : True
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : <=
TypeNameOfValue : System.String
Name : SideIndicator
IsInstance : True
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/348767.html
