GNU/Linux >> Znalost Linux >  >> Linux

Jak analyzovat Json pomocí skriptování Shell v Linuxu?

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
Související:Linux – Unix/Linux:rekurzivně vyhledávat soubory obsahující řetězec?

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.


Linux
  1. Jak změnit slovo v souboru pomocí skriptu linux shell

  2. Jak mohu provést rozdělení s proměnnými v prostředí Linuxu?

  3. Jak přejmenuji soubory s mezerami pomocí prostředí Linux?

  1. Jak používám Vagrant s libvirt

  2. Jak šifrovat soubory pomocí gocryptfs na Linuxu

  3. Jak zkontrolovat heslo v Linuxu?

  1. Základy Linuxu:Jak stahovat soubory do prostředí pomocí Wget

  2. Jak analyzovat a pěkně tisknout JSON pomocí nástrojů příkazového řádku Linuxu

  3. Jak změnit Shell v Linuxu