Preciso obter o valor após uma palavra específica

Preciso obter o valor após uma palavra específica

Preciso pegar o valor de "nome" desta linha

"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 a saída seja assim

sLVZt
ubg9x
lo3Qp

Responder1

Supondo que seu documento JSON seja 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"}]}

ou (já que os espaços em branco que não são de dados são irrelevantes para o 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"
    }
  ]
}

então use jqassim:

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

Isso extrai os valores da namechave em cada elemento do snapshotsarray.

Você também pode filtrar facilmente o resultado com base nos valores das outras chaves de várias maneiras:

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

Responder2

Se você estiver no Linux ou tiver acesso ao GNU grep, você pode fazer:

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

Alternativamente, em Perl:

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

Responder3

Tente isso,

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

sLVZt
ubg9x
lo3Qp

Responder4

Uma awksolução puramente baseada poderia ser assim:

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

Isto pegará a entrada e dividirá os "registros" (o que normalmente significaria umlinha) em ,e, em seguida, todos os registros em campos em :, deixando dois campos por registro. Se o primeiro campoterminain "name"(isso leva em consideração os colchetes/chaves iniciais), imprima o segundo campo, que é o valor atrás de :.

Se você quiser se livrar das aspas duplas, você pode usar

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

Atualizar

Como sua entrada de amostra alterada contém um líder "snapshots":, que também inclui o :mas de forma "desequilibrada", isso não funcionará mais. Como minha resposta foi "puramente awkbaseada", a única adaptação possível será muito mais envolvente e seria algo como:

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

Claramente, isso é muito menos elegante do que as grepabordagens baseadas em - e também menos portátil (não funcionará mawk, por exemplo).

informação relacionada