Convierta a csv desde json en powershell
este es mi csv:
"name,data
Play,http://{gho}.domain.com/
BDomain,domain.com
Charts,2
Compress,0
CompressJ,0" | ConvertFrom-Csv | ConvertTo-Json
Me da:
[
{
"name": "Play",
"data": "http://{gho}.domain.com/"
},
{
"name": "BDomain",
"data": "domain.com"
},
{
"name": "Charts",
"data": "2"
},
{
"name": "Compress",
"data": "0"
},
{
"name": "CompressJ",
"data": "0"
}
]
Ahora me gustaría recuperar ese csv de mi json, sin embargo, las cadenas de | ConvertFrom-Json | ConvertTo-CSV no funciona, y tengo curiosidad ¿por qué no?
Respuestas
Para complementar la útil respuesta de Steven con un breve resumen y una perspectiva de edición cruzada:
En PowerShell [Core] v7 + , no se necesita ningún esfuerzo adicional: agregar
| ConvertFrom-Json | ConvertTo-Csva su código funciona tal cual.En Windows PowerShell y PowerShell [Core] v6.x , es necesario forzar la enumeración de
ConvertFrom-Jsonla salida paraConvertTo-Csvque funcione correctamente, ya que, en contra del comportamiento habitual de PowerShell,ConvertFrom-Jsongenera una matriz JSON como un todo, como un solo objeto para la canalización .Es el hecho de que este comportamiento es inusual lo que provocó el cambio v7 +; consulte esta respuesta para obtener información general.
La forma más sencilla de forzar la enumeración, es decir, enviar los elementos de una matriz / colección de salida como un todo uno por uno a la tubería es utilizar
(...)el operador de agrupación .
# 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
Esto produce:
"name","data"
"Play","http://{gho}.domain.com/"
"BDomain","domain.com"
"Charts","2"
"Compress","0"
"CompressJ","0"
La salida de ConvertFrom-Jsonuna matriz única se transmite por la tubería como tal. Esta es una consecuencia de cómo ConvertFrom-Jsonse escribe su salida. Probablemente esté recopilando todo y generando la matriz en un Write-Outputcomando (implícito o no) en lugar de transmitir cada objeto por la tubería a medida que se crean. Probablemente sea una consecuencia de cómo está escrito el cmdlet y puede haber sido necesario.
Es probable que su código actual genere un csv como:
"Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
"5","5","5","1","System.Object[]","False","True","False"
Estas son las propiedades de la matriz, no los objetos que contiene. Una forma de evitarlo es simplemente estacionar los datos en una variable:
$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
Nota: si envía $ Json directamente,
$Json | ConvertFrom-Json | ConvertTo-Csv...es posible que tenga el mismo problema.
Iterar sobre los objetos Json también parece funcionar:
$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
Gracias a @notjustme, puedes acortar esto usando (...)like:
($json | ConvertFrom-Json) | ConvertTo-Csv
Nota: Corregido por la respuesta de mklement0 .
Todas estas opciones esencialmente colocan la matriz frente a la tubería para evitar el comportamiento interno de ConvertFrom-Json
Nuevamente, no estoy 100% seguro de por qué ConvertFrom-Json se comporta de esta manera. Actualizaré con información adicional cuando encuentre una explicación más formal.