GNU/Linux >> Linux Esercitazione >  >> Linux

Come analizzare Json con lo script della shell in Linux?

Ho un output JSON da cui devo estrarre alcuni parametri in Linux.

Questo è l'output 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
            }
        ]
    }

Voglio scrivere un file che contenga intestazione come ID istanza, tag come nome, centro di costo, proprietario. e al di sotto di determinati valori dall'output JSON. L'output qui fornito è solo un esempio.

Come posso farlo usando sed e awk ?

Risultato previsto :

 Instance id         Name                           cost centre             Owner
    i-1234576          RDS_Machine (us-east-1c)        1234                   Jyoti

Risposta accettata:

La disponibilità di parser in quasi tutti i linguaggi di programmazione è uno dei vantaggi di JSON come formato di scambio dati.

Piuttosto che provare a implementare un parser JSON, è probabile che tu stia meglio utilizzando uno strumento creato per l'analisi JSON come jq o un linguaggio di script generico con una libreria JSON.

Ad esempio, utilizzando jq, puoi estrarre ImageID dal primo elemento dell'array Instances come segue:

jq '.Instances[0].ImageId' test.json

In alternativa, per ottenere le stesse informazioni utilizzando la libreria JSON di Ruby:

ruby -rjson -e 'j = JSON.parse(File.read("test.json")); puts j["Instances"][0]["ImageId"]'

Non risponderò a tutte le tue domande e commenti rivisti, ma si spera che quanto segue sia sufficiente per iniziare.

Supponiamo di avere uno script Ruby in grado di leggere a da STDIN e generare la seconda riga nell'output di esempio [0]. Quello script potrebbe assomigliare a:

#!/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}"

Come potresti usare un copione del genere per raggiungere il tuo intero obiettivo? Bene, supponiamo che tu abbia già quanto segue:

  • un comando per elencare tutte le tue istanze
  • un comando per ottenere il json sopra per qualsiasi istanza nell'elenco e inviarlo a STDOU
Correlati:Linux – Unix/Linux:cercare ricorsivamente file contenenti una stringa?

Un modo sarebbe usare la tua shell per combinare questi strumenti:

echo -e "Instance idtNametcost centretOwner"
for instance in $(list-instances); do
    get-json-for-instance $instance | ./ugly-ruby-scriptrb
done

Ora, forse hai un singolo comando che ti dà un blob json per tutte le istanze con più elementi in quell'array "Istanze". Bene, in tal caso, dovrai solo modificare un po' lo script per scorrere l'array anziché utilizzare semplicemente il primo elemento.

Alla fine, il modo per risolvere questo problema è il modo per risolvere molti problemi in Unix. Scomponilo in problemi più facili. Trova o scrivi strumenti per risolvere il problema più semplice. Combina questi strumenti con la tua shell o altre funzionalità del sistema operativo.

[0] Nota che non ho idea di dove trovi il centro di costo, quindi l'ho appena inventato.


Linux
  1. Come uso Vagrant con libvirt

  2. Come crittografare i file con gocryptfs su Linux

  3. Nozioni di base su Linux:come scaricare file sulla shell con Wget

  4. Come cambiare una parola in un file con lo script della shell linux

  5. Come controllare la password con Linux?

Shell Scripting Parte I:Introduzione agli script bash

Come confrontare le directory con Meld su Linux

Script di shell per principianti - Come scrivere script Bash in Linux

Come proteggere i server Linux con SE Linux

Come modificare una shell utente in Linux

Bash Scripting:come generare e formattare il testo su Linux Shell