GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo analizar Json con secuencias de comandos de Shell en Linux?

Tengo una salida JSON de la que necesito extraer algunos parámetros en Linux.

Esta es la salida 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
            }
        ]
    }

Quiero escribir un archivo que contenga encabezado como ID de instancia, etiqueta como nombre, centro de costos, propietario. y debajo de eso, ciertos valores de la salida JSON. El resultado aquí dado es solo un ejemplo.

¿Cómo puedo hacer eso usando sed? y awk ?

Resultado esperado:

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

Respuesta aceptada:

La disponibilidad de analizadores en casi todos los lenguajes de programación es una de las ventajas de JSON como formato de intercambio de datos.

En lugar de intentar implementar un analizador JSON, probablemente sea mejor que utilice una herramienta creada para el análisis JSON, como jq, o un lenguaje de secuencias de comandos de propósito general que tenga una biblioteca JSON.

Por ejemplo, al usar jq, puede extraer el ID de imagen del primer elemento de la matriz Instancias de la siguiente manera:

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

Alternativamente, para obtener la misma información utilizando la biblioteca JSON de Ruby:

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

No responderé a todas sus preguntas y comentarios revisados, pero espero que lo siguiente sea suficiente para comenzar.

Suponga que tiene un script de Ruby que puede leer un STDIN y generar la segunda línea en su salida de ejemplo [0]. Esa secuencia de comandos podría parecerse 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}"

¿Cómo podría usar un guión así para lograr todo su objetivo? Bueno, supongamos que ya tiene lo siguiente:

  • un comando para enumerar todas sus instancias
  • un comando para obtener el json anterior para cualquier instancia en su lista y enviarlo a STDOU
Relacionado:Linux – Unix/Linux:¿buscar recursivamente archivos que contengan una cadena?

Una forma sería usar su caparazón para combinar estas herramientas:

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

Ahora, tal vez tenga un solo comando que le proporcione un json blob para todas las instancias con más elementos en esa matriz de "Instancias". Bueno, si ese es el caso, solo necesitará modificar un poco la secuencia de comandos para iterar a través de la matriz en lugar de simplemente usar el primer elemento.

Al final, la forma de resolver este problema es la forma de resolver muchos problemas en Unix. Divídelo en problemas más fáciles. Encuentre o escriba herramientas para resolver el problema más fácil. Combine esas herramientas con su shell u otras características del sistema operativo.

[0] Tenga en cuenta que no tengo idea de dónde obtiene el centro de costos, así que lo inventé.


Linux
  1. Cómo uso Vagrant con libvirt

  2. Cómo cifrar archivos con gocryptfs en Linux

  3. Conceptos básicos de Linux:cómo descargar archivos en el Shell con Wget

  4. Cómo cambiar Shell en Linux

  5. Cómo cambiar una palabra en un archivo con script de shell de Linux

Shell Scripting Parte I:Primeros pasos con bash scripting

Cómo comparar directorios con Meld en Linux

Shell Scripting para principiantes:cómo escribir Bash Scripts en Linux

Cómo asegurar servidores Linux con SE Linux

Cómo cambiar un Shell de usuario en Linux

Bash Scripting:cómo generar y formatear texto en Linux Shell