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 ciertos valores de la salida JSON. La salida aquí dada es solo un ejemplo.
¿Cómo puedo hacer eso usando sed
y awk
?
Rendimiento esperado :
Instance id Name cost centre Owner
i-1234576 RDS_Machine (us-east-1c) 1234 Jyoti
text-processing
sed
awk
json
usuario3086014
fuente
fuente
Respuestas:
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 usar una herramienta creada para el análisis JSON como jq o un lenguaje de script de propósito general que tenga una biblioteca JSON.
Por ejemplo, usando jq, puede extraer el ID de imagen del primer elemento de la matriz de instancias de la siguiente manera:
Alternativamente, para obtener la misma información usando la biblioteca JSON de Ruby:
No responderé a todas sus preguntas y comentarios revisados, pero espero que lo siguiente sea suficiente para comenzar.
Suponga que tiene un script Ruby que puede leer un STDIN y generar la segunda línea en su salida de ejemplo [0]. Ese guión podría parecerse a algo como:
¿Cómo podrías usar un guión para lograr tu objetivo? Bueno, supongamos que ya tienes lo siguiente:
Una forma sería usar su shell para combinar estas herramientas:
Ahora, tal vez tenga un solo comando que le dé un blob json para todas las instancias con más elementos en esa matriz de "Instancias". Bueno, si ese es el caso, solo tendrá que modificar un poco el script para recorrer 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ídalo en problemas más fáciles. Encuentra o escribe 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é.
fuente
Puede usar el siguiente script de Python para analizar esos datos. Supongamos que tiene datos JSON de matrices en archivos como
array1.json
,array2.json
etc.Y luego solo corre:
No he visto costos en sus datos, por eso no los incluí.
De acuerdo con la discusión en los comentarios, he actualizado el script parse.py:
Puede intentar ejecutar el siguiente comando:
fuente
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()
si tiene todos los datos json de las matrices en archivos como array1.json, array2.json, ... y así sucesivamente, podría intentar ejecutarlo de esta manera:# for x in
ls * .json; do python parse.py $x; done
El siguiente código jq:
utilizado como:
daría salida:
Algunos consejos para entender el código:
from_entries
toma un conjunto de objetos como{key:a, value:b}
y lo convierte en un objeto con los pares clave / valor correspondientes ({a: b}
);Key
yValue
en laTags
matriz tenían que convertirse a minúsculas;Para obtener más detalles, consulte el tutorial y el manual de jq en https://stedolan.github.io/jq/
fuente
(.Tags | map({Value, Key}) | from_entries) as $tags
, sin convertir las claves a minúsculas.Otros han proporcionado respuestas generales para su pregunta que demuestran buenas formas de analizar json, sin embargo, como usted, estaba buscando una forma de extraer una identificación de instancia de aws usando una herramienta central como awk o sed sin depender de otros paquetes. Para lograr esto, puede pasar el argumento "--output = text" a su comando aws que le dará una cadena awk analizable. Con eso, simplemente puede obtener la ID de instancia usando algo como lo siguiente ...
fuente
Jshon está disponible en varias distribuciones:
Mala explicación:
-e uu
extraerá el objetouu
,-a
hará que la matriz sea utilizable (no estoy seguro de haber redactado correctamente este, pero de todos modos ...),-u
decodificará la cadena,-p
volverá al elemento anterior (parece que-i N
, siendo N cualquier número, tiene el mismo efecto) .Dependiendo de su caso, la salida puede requerir algún tratamiento posterior (como el suyo, como puede ver).
Jshon
sin embargo, no parece robusto frente a la malformación de JSON (sus "Etiquetas" con comas antes del cierre de la llave generarán un error).Alguien mencionó jsawk en otro hilo, pero no lo he probado.
fuente
Si esto se limita al caso de uso de AWS proporcionado anteriormente, debe usar los indicadores --query y --output para su llamada a la API CLI
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html
fuente
Aquí hay una sugerencia:
No es perfecto, pero funcionaría si lo modificas un poco.
Básicamente se utiliza
pr
para imprimir cada resultado del conjunto por columna. Cada conjunto de resultados se devuelve mediante la sustitución del proceso que analiza el archivo JSON y devuelve valores basados en la clave.Esto funciona de manera similar a como se describe en: Dado el contenido clave-valor, ¿cómo puedo agrupar los valores por clave y ordenar por valor?
fuente
Echa un vistazo a la
jtc
herramienta cli:permite extraer fácilmente la información requerida de su json (suponiendo que esté
file.json
, por cierto, su JSON necesita ser reparado, hay un par de comas adicionales allí):fuente
jq "." recovery.js | head -n 20
traduce su archivo jason a algo legible como este:
Ahora debería ser posible analizar sus datos con cualquier herramienta estándar
fuente