Konvertieren Sie von json in Powershell zu CSV
das ist mein csv:
"name,data
Play,http://{gho}.domain.com/
BDomain,domain.com
Charts,2
Compress,0
CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json
Gibt mir:
[
{
"name": "Play",
"data": "http://{gho}.domain.com/"
},
{
"name": "BDomain",
"data": "domain.com"
},
{
"name": "Charts",
"data": "2"
},
{
"name": "Compress",
"data": "0"
},
{
"name": "CompressJ",
"data": "0"
}
]
Ich möchte jetzt diese CSV von meinem JSON zurückbekommen, jedoch die Ketten von | ConvertFrom-Json | ConvertTo-CSV funktioniert nicht und ich bin gespannt, warum nicht?
Antworten
Um Stevens hilfreiche Antwort mit einer kurzen Zusammenfassung und einer übergreifenden Perspektive zu ergänzen :
In PowerShell [Core] v7 + ist kein zusätzlicher Aufwand erforderlich: Das Anhängen
| ConvertFrom-Json | ConvertTo-Csvan Ihren Code funktioniert unverändert .In Windows PowerShell und PowerShell [Core] v6.x müssen Sie die Aufzählung der
ConvertFrom-JsonAusgabe erzwingen , damitConvertTo-Csvsie ordnungsgemäß funktioniert, da entgegen dem üblichen Verhalten von PowerShellConvertFrom-Jsonein JSON-Array als Ganzes als einzelnes Objekt an die Pipeline ausgegeben wird .Es ist die Tatsache, dass dieses Verhalten ungewöhnlich ist , die zur Änderung von Version 7 + geführt hat. Hintergrundinformationen finden Sie in dieser Antwort .
Der einfachste Weg, die Aufzählung zu erzwingen, dh die Elemente eines Arrays / einer Sammlung als Ganzes einzeln an die Pipeline zu senden, ist die Verwendung
(...)des Gruppierungsoperators .
# Works in all PowerShell versions, but in v7+ the (...) is no longer necessary.
(
"name,data
Play,http://{gho}.domain.com/
BDomain,domain.com
Charts,2
Compress,0
CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json |
ConvertFrom-Json
) | ConvertTo-Csv -NoTypeInformation
Dies ergibt:
"name","data"
"Play","http://{gho}.domain.com/"
"BDomain","domain.com"
"Charts","2"
"Compress","0"
"CompressJ","0"
Die Ausgabe von ConvertFrom-Jsonist ein einzelnes Array, das als solches über die Pipeline geleitet wird. Dies ist eine Folge davon, wie ConvertFrom-Jsondie Ausgabe geschrieben wird. Es geht wahrscheinlich darum, alles zu sammeln und das Array in einem Write-OutputBefehl (implizit oder auf andere Weise) auszugeben, anstatt jedes Objekt beim Erstellen über die Pipeline zu streamen. Dies hängt wahrscheinlich damit zusammen, wie das Cmdlet geschrieben wurde und möglicherweise erforderlich war.
Ihr aktueller Code generiert wahrscheinlich eine CSV wie:
"Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
"5","5","5","1","System.Object[]","False","True","False"
Dies sind die Eigenschaften des Arrays, nicht die darin enthaltenen Objekte. Eine Möglichkeit, dies zu umgehen, besteht darin, die Daten in einer Variablen zu parken:
$Json = "name,data Play,http://{gho}.domain.com/ BDomain,domain.com Charts,2 Compress,0 CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json # Now you can convert back to csv without issue: $Json = $Json | ConvertFrom-Json $Json | ConvertTo-Csv -NoTypeInformation
Hinweis: Wenn Sie $ Json direkt senden,
$Json | ConvertFrom-Json | ConvertTo-Csv...haben Sie möglicherweise das gleiche Problem.
Das Iterieren über die Json-Objekte scheint ebenfalls zu funktionieren:
$Json = "name,data Play,http://{gho}.domain.com/ BDomain,domain.com Charts,2 Compress,0 CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json $Json |
ConvertFrom-Json |
ForEach-Object{ $_ } |
ConvertTo-Csv -NoTypeInformation
Dank @notjustme können Sie dies (...)wie folgt verkürzen :
($json | ConvertFrom-Json) | ConvertTo-Csv
Hinweis: Korrigiert gemäß der Antwort von mklement0 .
Bei all diesen Optionen wird das Array im Wesentlichen vor der Pipe platziert, um das interne Verhalten von zu umgehen ConvertFrom-Json
Wieder nicht 100% sicher, warum sich ConvertFrom-Json so verhält. Ich werde mit zusätzlichen Informationen aktualisieren, wenn ich eine formellere Erklärung finde.