Eu tenho uma saída JSON da qual preciso extrair alguns parâmetros no Linux.
Esta é a saída JSON:
{
"OwnerId": "121456789127",
"ReservationId": "r-48465168",
"Groups": [],
"Instances": [
{
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": null,
"RootDeviceType": "ebs",
"State": {
"Code": 16,
"Name": "running"
},
"EbsOptimized": false,
"LaunchTime": "2014-03-19T09:16:56.000Z",
"PrivateIpAddress": "10.250.171.248",
"ProductCodes": [
{
"ProductCodeId": "aacglxeowvn5hy8sznltowyqe",
"ProductCodeType": "marketplace"
}
],
"VpcId": "vpc-86bab0e4",
"StateTransitionReason": null,
"InstanceId": "i-1234576",
"ImageId": "ami-b7f6c5de",
"PrivateDnsName": "ip-10-120-134-248.ec2.internal",
"KeyName": "Test_Virginia",
"SecurityGroups": [
{
"GroupName": "Test",
"GroupId": "sg-12345b"
}
],
"ClientToken": "VYeFw1395220615808",
"SubnetId": "subnet-12345314",
"InstanceType": "t1.micro",
"NetworkInterfaces": [
{
"Status": "in-use",
"SourceDestCheck": true,
"VpcId": "vpc-123456e4",
"Description": "Primary network interface",
"NetworkInterfaceId": "eni-3619f31d",
"PrivateIpAddresses": [
{
"Primary": true,
"PrivateIpAddress": "10.120.134.248"
}
],
"Attachment": {
"Status": "attached",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "eni-attach-9210dee8",
"AttachTime": "2014-03-19T09:16:56.000Z"
},
"Groups": [
{
"GroupName": "Test",
"GroupId": "sg-123456cb"
}
],
"SubnetId": "subnet-31236514",
"OwnerId": "109030037527",
"PrivateIpAddress": "10.120.134.248"
}
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": null,
"AvailabilityZone": "us-east-1c"
},
"Hypervisor": "xen",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": false,
"VolumeId": "vol-37ff097b",
"AttachTime": "2014-03-19T09:17:00.000Z"
}
}
],
"Architecture": "x86_64",
"KernelId": "aki-88aa75e1",
"RootDeviceName": "/dev/sda1",
"VirtualizationType": "paravirtual",
"Tags": [
{
"Value": "Server for testing RDS feature in us-east-1c AZ",
"Key": "Description"
},
{
"Value": "RDS_Machine (us-east-1c)",
"Key": "Name"
},
{
"Value": "1234",
"Key": "cost.centre",
},
{
"Value": "Jyoti Bhanot",
"Key": "Owner",
}
],
"AmiLaunchIndex": 0
}
]
}
Quero escrever um arquivo que contenha título como ID da instância, marca como nome, centro de custo, proprietário. e abaixo desse valor da saída JSON. A saída aqui dada é apenas um exemplo.
Como posso fazer isso usando sed
e awk
?
Saída esperada:
Instance id Name cost centre Owner
i-1234576 RDS_Machine (us-east-1c) 1234 Jyoti
text-processing
sed
awk
json
user3086014
fonte
fonte
Respostas:
A disponibilidade de analisadores em quase todas as linguagens de programação é uma das vantagens do JSON como formato de intercâmbio de dados.
Em vez de tentar implementar um analisador JSON, provavelmente é melhor usar uma ferramenta criada para a análise JSON, como jq, ou uma linguagem de script de uso geral que possui uma biblioteca JSON.
Por exemplo, usando jq, você pode extrair o ImageID do primeiro item da matriz Instances da seguinte maneira:
Como alternativa, para obter as mesmas informações usando a biblioteca JSON do Ruby:
Não responderei a todas as suas perguntas e comentários revisados, mas espero que o seguinte seja suficiente para você começar.
Suponha que você tenha um script Ruby que possa ler um de STDIN e gerar a segunda linha no exemplo de saída [0]. Esse script pode ser algo como:
Como você pode usar esse script para realizar todo o seu objetivo? Bem, suponha que você já tenha o seguinte:
Uma maneira seria usar seu shell para combinar essas ferramentas:
Agora, talvez você tenha um único comando que fornece um blob json para todas as instâncias com mais itens na matriz "Instâncias". Bem, se for esse o caso, você precisará modificar um pouco o script para percorrer a matriz em vez de simplesmente usar o primeiro item.
No final, a maneira de resolver esse problema, é a maneira de resolver muitos problemas no Unix. Divida-o em problemas mais fáceis. Encontre ou escreva ferramentas para resolver o problema mais fácil. Combine essas ferramentas com seu shell ou outros recursos do sistema operacional.
[0] Note que eu não tenho ideia de onde você obtém o centro de custo, então acabei de inventar.
fonte
Você pode usar o seguinte script python para analisar esses dados. Vamos supor que você tem dados JSON de matrizes em arquivos como
array1.json
,array2.json
e assim por diante.E então apenas execute:
Não vi custos nos seus dados, por isso não incluí isso.
De acordo com a discussão nos comentários, eu atualizei o script parse.py:
Você pode tentar executar o seguinte comando:
fonte
import json from pprint import pprint jdata = open('example.json') data = json.load(jdata) print "InstanceId", " - ", "Name", " - ", "Owner" print data["Instances"][0]["InstanceId"], " - " ,data["Instances"][0]["Tags"][1]["Value"], " - " ,data["Instances"][0]["Tags"][2]["Value"] jdata.close()
Modifiquei um pouco esse script python: se você tiver todos os dados json de matrizes em arquivos como array1.json, array2.json, ... e assim por diante, tente executar da seguinte maneira:# for x in
ls * .json; do python parse.py $x; done
O seguinte código jq:
usado como:
produziria:
Alguns ponteiros para entender o código:
from_entries
pega uma matriz de objetos como{key:a, value:b}
e a transforma em um objeto com os pares chave / valor correspondentes ({a: b}
);Key
eValue
naTags
matriz tiveram que ser convertidas para minúsculas;Para obter mais detalhes, consulte o tutorial e o manual do jq em https://stedolan.github.io/jq/
fonte
(.Tags | map({Value, Key}) | from_entries) as $tags
, sem converter chaves em minúsculas.Outros forneceram respostas gerais para sua pergunta que demonstram boas maneiras de analisar o json, no entanto, como você, estava procurando uma maneira de extrair um ID de instância do aws usando uma ferramenta principal como o awk ou o sed sem depender de outros pacotes. Para fazer isso, você pode passar o argumento "--output = text" para o seu comando aws, que fornecerá uma string aws parsable. Com isso, você pode simplesmente obter o ID da instância usando algo como o seguinte ...
fonte
O Jshon está disponível em várias distribuições:
Má explicação:
-e uu
extrairá o objetouu
,-a
tornará a matriz utilizável (não tenho certeza de que eu escrevi corretamente esta, mas enfim…),-u
decodificará a string,-p
voltará ao item anterior (parece que-i N
, N sendo qualquer número, tem o mesmo efeito) .Dependendo do seu caso, a saída pode exigir algum pós-tratamento (como o seu, como você pode ver).
Jshon
No entanto, parece robusto contra a malformação JSON (suas "Tags" com vírgulas antes do colchete de fechamento causam um erro).Alguém mencionou o jsawk em outro tópico, mas eu não testei.
fonte
Se isso estiver limitado ao caso de uso da AWS fornecido acima, você deve usar os sinalizadores --query e --output para sua chamada da API da CLI
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html
fonte
Aqui está uma sugestão de uma linha:
Não é perfeito, mas funcionaria se você o ajustar um pouco.
É basicamente usando
pr
para imprimir cada resultado definido por coluna. Cada conjunto de resultados é retornado por substituição de processo que analisa o arquivo JSON e retorna valores com base na chave.Isso funciona de maneira semelhante à descrita em: Dado o conteúdo do valor-chave, como agrupar valores por chave e classificar por valor?
fonte
Dê uma olhada na
jtc
ferramenta cli:permite extrair facilmente as informações necessárias do seu json (supondo que esteja dentro
file.json
, aliás, seu JSON precisa ser corrigido, há algumas vírgulas extras):fonte
jq "." recovery.js | head -n 20
converte seu arquivo jason para algo legível como este:
Agora deve ser possível analisar seus dados com qualquer ferramenta padrão
fonte