Necesito obtener el valor después de una palabra específica.

Necesito obtener el valor después de una palabra específica.

Necesito obtener el valor de "nombre" de esta línea

"snapshots": [{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2",{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}

Espero que el resultado sea así.

sLVZt
ubg9x
lo3Qp

Respuesta1

Suponiendo que su documento JSON sea válido, como

{"snapshots":[{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2"},{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}

o (dado que los espacios en blanco que no son datos son irrelevantes para el formato),

{
  "snapshots": [
    {
      "name": "sLVZt",
      "user": "comment",
      "current": "n",
      "created": "2015-03-11 05:28:02"
    },
    {
      "name": "ubg9x",
      "user": "test2"
    },
    {
      "name": "lo3Qp",
      "user": "test3",
      "current": "y",
      "created": "2015-03-11 06:02:46"
    }
  ]
}

entonces usa jqasí:

$ jq -r '.snapshots[].name' file.json
sLVZt
ubg9x
lo3Qp

Esto extrae los valores de la nameclave en cada elemento de la snapshotsmatriz.

También puedes filtrar fácilmente el resultado según los valores de las otras claves de varias maneras:

$ jq -r '.snapshots[] | select(.current == "y").name' file.json
lo3Qp
$ jq -r '.snapshots[] | select(.current != "n").name' file.json
ubg9x
lo3Qp

Respuesta2

Si estás en Linux o tienes acceso a GNU grep, puedes hacer:

$ grep -oP '"name":"\K[^"]+' file 
sLVZt
ubg9x
lo3Qp

Alternativamente, en Perl:

$ perl -lne 'print join "\n", /"name":"([^"]+)/g' file 
sLVZt
ubg9x
lo3Qp

Respuesta3

Prueba esto,

 sed 's/,/\n/g' file | awk -F '"' '$2~/name/ {print $(NF-1)}'

sLVZt
ubg9x
lo3Qp

Respuesta4

Una awksolución puramente basada podría verse así:

awk -F':' -v RS=',' '$1 ~ /"name"$/ {print $2}' file

Esto tomará la entrada y dividirá los "registros" (lo que normalmente significaría unlínea) en ,, y luego todos los registros en los campos en :, dejando dos campos por registro. Si el primer campoterminaen "name"(esto tiene en cuenta las llaves cuadradas o rizadas iniciales), imprima el segundo campo, que es el valor detrás del :.

Si desea deshacerse de las comillas dobles de refuerzo, puede utilizar

awk -F':' -v RS=',' '$1 ~ /"name"$/ {gsub("\"","",$2); print $2}' file

Actualizar

Dado que su entrada de muestra modificada contiene un encabezado "snapshots":, que también incluye :pero de forma "desequilibrada", esto ya no funcionará. Como mi respuesta decía "puramente awkbasada", la única adaptación posible será mucho más complicada y se vería así:

awk '{n=patsplit($0,field,"\"[^\"]*\":\"[^\"]*\""); for (i=1;i<=n;i++) {split(field[i],elem,":"); if (elem[1]=="\"name\"") print elem[2];};}' file

Claramente, esto es mucho menos elegante que los grepenfoques basados ​​en -, y también menos portátil (no funcionará en mawk, por ejemplo).

información relacionada