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 jq
assim:
$ jq -r '.snapshots[].name' file.json
sLVZt
ubg9x
lo3Qp
Isso extrai os valores da name
chave em cada elemento do snapshots
array.
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 awk
soluçã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 awk
baseada", 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 grep
abordagens baseadas em - e também menos portátil (não funcionará mawk
, por exemplo).