Logró obtener los datos JSON con

$R= Invoke-WebRequest -Uri $url -Headers $headers -ContentType "application/json"   -Method Get -UseBasicParsing
$x = $R.Content | Out-String | ConvertFrom-Json 

Ahora tengo un archivo JSON como este:

{
  "id": 1000,
  "name_with_namespace": "myProjectName1",

},
{
  "id": 1001,
  "name_with_namespace": "myProjectName2",

},
{
  "id": 1002,
  "name_with_namespace": "myProjectName3",

}

Ahora necesito extraer toda la aparición de "name_with_namespace" y "id" donde "name_with_namespace" = "myProjectName.*"

¿Cómo puedo hacerlo de una vez?

He probado esto:

foreach ($name in $x.name_with_namespace) {
    if ( $name -match ".*myProjectName.*" ) {    
        write-host "$name - $x.id"               
    }   
}

Pero tengo esto:

myProjectName1 1000 1001 1002
myProjectName2 1000 1001 1002
myProjectName3 1000 1001 1002

Entiendo que el problema está en $ x.id, ¿cómo puedo obtener el valor correcto en lugar de todo?

Mi salida esperada es

myProjectName1 1000
myProjectName2 1001
myProjectName3 1002
1
ClaudioM 6 mar. 2018 a las 19:55

3 respuestas

La mejor respuesta

Está perforando un nivel demasiado lejos cuando define su bucle. Simplemente itere $x y luego verifique la propiedad específica dentro del ciclo.

foreach ($name in $x) {
    if ( $name.name_with_namespace -match ".*myProjectName.*" ) {    
        write-host "$($name.name_with_namespace) - $($name.id)"               
    }   
}

Editar: en una nota al margen, puede simplificar su -match a solo "myProjectName" y funcionará igual de bien, y probablemente más rápido.

7
TheMadTechnician 6 mar. 2018 a las 17:26

ConvertFrom-Json tiene un comportamiento extraño con tuberías. El problema es que ConvertFrom-Json envuelve la matriz JSON en una matriz y luego pasa toda la matriz por la tubería como un elemento. Esto está bien en la mayoría de los casos, pero si el nivel más externo es una matriz JSON, entonces toda la matriz se pasa como un solo objeto a la tubería.

Comparar:

PS> ConvertFrom-Json '[1, 2, 3]' | ForEach-Object  {": $_"}
: 1 2 3

PS> (ConvertFrom-Json '[1, 2, 3]') | ForEach-Object  {": $_"}
: 1
: 2
: 3

PS> $x = ConvertFrom-Json '[1, 2, 3]'
PS> $x | ForEach-Object  {": $_"}
: 1
: 2
: 3
PS> ,$x | ForEach-Object  {": $_"}
: 1 2 3

Tenga en cuenta que con ese último ejemplo podemos duplicar el problema con el operador de coma unaria.

El problema se ha informado aquí para PowerShell Core 6.

Pruebe este código:

$j = @'
[
    {
        "id": 1000,
        "name_with_namespace": "myProjectName1"
    },
    {
        "id": 1001,
        "name_with_namespace": "myProjectName2"
    },
    {
        "id": 1002,
        "name_with_namespace": "myProjectName3"
    }
]
'@

($j | Out-String | ConvertFrom-Json) |
Where-Object name_with_namespace -match ".*myProjectName.*" |
ForEach-Object {
    "$($_.name_with_namespace) $($_.id)"
}
0
Bacon Bits 6 mar. 2018 a las 18:45

Básicamente, ya has obtenido el json con el parentnode, así que no estoy cubriendo esa parte. Suponiendo que ya tiene el nodo primario, puede hacer esto directamente:

$a=@"
{"ParentNode":[
    {"id":1000,"name_with_namespace":"myProjectName"},
    {"id":1001,"name_with_namespace":"myProjectName2"},
    {"id":1002,"name_with_namespace":"myProjectName3"}
]}
"@ 

($a | ConvertFrom-Json).ParentNode

Salida:

id name_with_namespace
  -- -------------------
1000 myProjectName      
1001 myProjectName2     
1002 myProjectName3

Puedes analizar lo que quieras. No hay problema en esa parte. Asegúrese de que su json esté estructurado como uno que está recibiendo del restAPI. usando métodos de puntos, puede ir a cualquier nivel y también puede seleccionarlos directamente usando select-object también.

Espero que ayude.

1
Ranadip Dutta 6 mar. 2018 a las 17:21