我已經閱讀了幾篇關于使用 PowerShell 到 CSV 的文章(例如Convert JSON to CSV using PowerShell)。我還讀到在腳本中使用管道語法是一種相對較差的形式——它實際上是用于命令列的,并且隨著時間的推移會給開發人員維護帶來麻煩。
使用此示例 JSON 檔案...
[
{
"a": "Value 1",
"b": 20,
"g": "Arizona"
},
{
"a": "Value 2",
"b": 40
},
{
"a": "Value 3"
},
{
"a": "Value 4",
"b": 60
}
]
...這段代碼...
((Get-Content -Path $pathToInputFile -Raw) | ConvertFrom-Json) | Export-CSV $pathToOutputFile -NoTypeInformation
...按預期創建一個包含 CSV 的檔案。
"a","b","g"
"Value 1","20","Arizona"
"Value 2","40",
"Value 3",,
"Value 4","60",
這段代碼...
$content = Get-Content -Path $pathToInputFile -Raw
$psObj = ConvertFrom-Json -InputObject $content
Export-Csv -InputObject $psObj -LiteralPath $pathToOutputFile -NoTypeInformation
...創建一個包含廢話的檔案:
"Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
"4","4","4","1","System.Object[]","False","True","False"
看起來可能是一個物件定義(?)。
有什么區別?轉換代碼時我錯過了哪些 PowerShell 細微差別?
Powershell - Export a List of Objects to CSV的答案說問題出在-InputObject導致物件而不是內容被發送到 Export-Csv 的選項上,但沒有說明如何在不使用管道語法的情況下解決問題. 我在想類似的東西-InputObject $psObj.contents。我意識到這不是真的,但我Get-Members沒有向我展示任何看起來可以解決這個問題的東西。
uj5u.com熱心網友回復:
這并不是一個答案,而只是為了讓您模糊地表示正在做什么ConvertTo-Csv和Export-Csv正在做什么,并幫助您理解為什么-InputObject要從管道中系結并且不應該手動使用。
function ConvertTo-Csv2 {
param(
[parameter(ValueFromPipeline)]
[Object]$InputObject
)
begin
{
$isFirstObject = $true
$re = [regex]'"'
$csv = [System.Text.StringBuilder]::new()
filter Normalize {
if($re.Match($_).Success)
{
return $_.Replace('"','""')
}
$_
}
}
process
{
if($isFirstObject)
{
$headers = $InputObject.PSObject.Properties.Name | Normalize
$isFirstObject = $false
$line = [string]::Format('"{0}"',($headers -join '","'))
$null = $csv.AppendLine($line)
}
$values = foreach($prop in $headers)
{
$InputObject.$prop | Normalize
}
$line = [string]::Format('"{0}"',($values -join '","'))
$null = $csv.AppendLine($line)
}
end
{
$csv.ToString().Trim()
}
}
uj5u.com熱心網友回復:
Get-Members 沒有向我顯示任何看起來可以解決此問題的內容
獲取會員
這是因為您傳遞值的方式具有不同的行為。
管道列舉值,它幾乎就像一個foreach($item in $pipeline). 傳遞引數會跳過
在這里,我有一個包含3 個字母的陣列。
$Letters = 'a'..'c'
我得到不同的型別
Get-Member -InputObject $Letters
# [Object[]]
# [char]
$letters | Get-Member
為每個專案處理
$letters | ForEach-Object {
"iteration: $_"
}
iteration: a
iteration: b
iteration: c
相比于
ForEach-Object -InputObject $Letters {
"iteration: $_"
}
iteration: a b c
檢測型別
以下是檢查物件的幾種方法。
使用ClassExplorer
PS> ($Letters).GetType().FullName
PS> ($Letters[0]).GetType().FullName # first child
System.Object[]
System.Char
PS> $Letters.count
PS> $Letters[0].Count
3
1
$Letters.pstypenames -join ', '
$Letters[0].pstypenames -join ', '
System.Object[], System.Array, System.Object
System.Char, System.ValueType, System.Object
提示:$null.count總是回傳 0。它不會拋出錯誤。
if($neverExisted.count -gt 1) { ... }
雜項
我還讀到在腳本中使用管道語法的形式相對較差
這不是真的,Powershell 是圍繞管道物件設計的。
提示:$null.count總是回傳 0。它不會拋出錯誤。
也許他們在談論
示例 2:緩慢的操作
在某些情況下,當您需要快速的東西時,Foreach-Objectover a的開銷foreach可能是一個問題。它使你不得不使用一些額外的語法。
如果你真的需要速度,你可能應該呼叫 dotnet 方法。
示例 1:可以使用引數時的管道
我猜他們的意思是在可以傳遞引數的情況下傳遞一個變數?
$text = "hi-world"
# then
$text | Write-Host
# vs
Write-Host -InputObject $Text
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/405523.html
標籤:
