Mám výstup JSON, ze kterého potřebuji extrahovat pár parametrů v Linuxu.
Toto je výstup 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
}
]
}
Chci napsat soubor, který obsahuje nadpis jako id instance, tag jako název, nákladové středisko, vlastník. a pod tím určité hodnoty z výstupu JSON. Zde uvedený výstup je pouze příkladem.
Jak to mohu udělat pomocí sed
a awk
?
Očekávaný výstup:
Instance id Name cost centre Owner
i-1234576 RDS_Machine (us-east-1c) 1234 Jyoti
Přijatá odpověď:
Dostupnost analyzátorů v téměř každém programovacím jazyce je jednou z výhod JSON jako formátu pro výměnu dat.
Než se pokoušet implementovat analyzátor JSON, pravděpodobně bude lepší použít buď nástroj vytvořený pro analýzu JSON, jako je jq, nebo obecný skriptovací jazyk, který má knihovnu JSON.
Například pomocí jq můžete vytáhnout ImageID z první položky pole Instances následovně:
jq '.Instances[0].ImageId' test.json
Případně získat stejné informace pomocí knihovny JSON Ruby:
ruby -rjson -e 'j = JSON.parse(File.read("test.json")); puts j["Instances"][0]["ImageId"]'
Nebudu odpovídat na všechny vaše upravené otázky a komentáře, ale doufejme, že následující postačí, abyste mohli začít.
Předpokládejme, že jste měli skript Ruby, který dokázal přečíst a ze STDIN a vypsat druhý řádek ve vašem příkladu výstupu[0]. Tento skript může vypadat nějak takto:
#!/usr/bin/env ruby
require 'json'
data = JSON.parse(ARGF.read)
instance_id = data["Instances"][0]["InstanceId"]
name = data["Instances"][0]["Tags"].find {|t| t["Key"] == "Name" }["Value"]
owner = data["Instances"][0]["Tags"].find {|t| t["Key"] == "Owner" }["Value"]
cost_center = data["Instances"][0]["SubnetId"].split("-")[1][0..3]
puts "#{instance_id}t#{name}t#{cost_center}t#{owner}"
Jak byste mohli použít takový skript k dosažení celého svého cíle? Předpokládejme, že jste již měli následující:
- příkaz pro výpis všech vašich instancí
- příkaz pro získání výše uvedeného json pro jakoukoli instanci ve vašem seznamu a jeho výstup do STDOU
Jedním ze způsobů by bylo použít váš shell ke kombinaci těchto nástrojů:
echo -e "Instance idtNametcost centretOwner"
for instance in $(list-instances); do
get-json-for-instance $instance | ./ugly-ruby-scriptrb
done
Nyní možná máte jeden příkaz, který vám poskytne jeden blob json pro všechny instance s více položkami v tomto poli „Instance“. Pokud je to tak, budete muset skript trochu upravit, abyste mohli polem iterovat, místo abyste jednoduše použili první položku.
Nakonec, způsob, jak vyřešit tento problém, je způsob, jak vyřešit mnoho problémů v Unixu. Rozdělte to na jednodušší problémy. Najděte nebo napište nástroje k vyřešení jednoduššího problému. Zkombinujte tyto nástroje s vaším shellem nebo jinými funkcemi operačního systému.
[0] Všimněte si, že nemám ponětí, odkud máte nákladové centrum, takže jsem si to jen vymyslel.