Mam wyjście JSON, z którego muszę wyodrębnić kilka parametrów w systemie Linux.
To jest wyjście 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
}
]
}
Chcę napisać plik, który zawiera nagłówek taki jak identyfikator instancji, tag jak nazwa, centrum kosztów, właściciel. a poniżej niektórych wartości z wyjścia JSON. Dane wyjściowe podane tutaj są tylko przykładem.
Jak mogę to zrobić za pomocą sed
i awk
?
Oczekiwany wynik :
Instance id Name cost centre Owner
i-1234576 RDS_Machine (us-east-1c) 1234 Jyoti
text-processing
sed
awk
json
użytkownik3086014
źródło
źródło
Odpowiedzi:
Dostępność parserów w prawie każdym języku programowania jest jedną z zalet JSON jako formatu wymiany danych.
Zamiast próbować zaimplementować parser JSON, prawdopodobnie lepiej jest użyć albo narzędzia zbudowanego dla parsowania JSON, takiego jak jq, albo języka skryptowego ogólnego przeznaczenia, który ma bibliotekę JSON.
Na przykład, używając jq, możesz wyciągnąć ImageID z pierwszego elementu tablicy Instances w następujący sposób:
Alternatywnie, aby uzyskać te same informacje za pomocą biblioteki JSON Ruby:
Nie odpowiem na wszystkie twoje poprawione pytania i komentarze, ale mam nadzieję, że poniższe informacje pomogą Ci zacząć.
Załóżmy, że masz skrypt Ruby, który może odczytać STDIN i wypisać drugi wiersz w twoim przykładowym wyniku [0]. Ten skrypt może wyglądać mniej więcej tak:
Jak możesz użyć takiego skryptu, aby osiągnąć cały swój cel? Załóżmy, że masz już następujące elementy:
Jednym ze sposobów byłoby użycie powłoki do połączenia tych narzędzi:
Być może masz jedno polecenie, które daje jeden blok json dla wszystkich instancji z większą liczbą elementów w tablicy „Instancje”. Cóż, w takim przypadku wystarczy zmodyfikować skrypt, aby iterować tablicę, a nie po prostu użyć pierwszego elementu.
W końcu sposób na rozwiązanie tego problemu jest sposobem na rozwiązanie wielu problemów w Uniksie. Podziel go na łatwiejsze problemy. Znajdź lub napisz narzędzia, aby rozwiązać łatwiejszy problem. Połącz te narzędzia z powłoką lub innymi funkcjami systemu operacyjnego.
[0] Pamiętaj, że nie mam pojęcia, skąd bierzesz centrum kosztów, więc właśnie to wymyśliłem.
źródło
Możesz użyć następującego skryptu Pythona do parsowania tych danych. Załóżmy, że masz dane JSON z tablic w plikach, takich jak
array1.json
,array2.json
i tak dalej.A następnie po prostu uruchom:
Nie widziałem kosztów w twoich danych, dlatego tego nie uwzględniłem.
Zgodnie z dyskusją w komentarzach zaktualizowałem skrypt parse.py:
Możesz spróbować uruchomić następujące polecenie:
źródło
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()
jeśli masz wszystkie dane json z tablic w plikach takich jak array1.json, array2.json, ... i tak dalej, możesz spróbować uruchomić to w następujący sposób:# for x in
ls * .json; do python parse.py $x; done
Następujący kod jq:
używane jak:
wyprowadziłby:
Kilka wskazówek, aby zrozumieć kod:
from_entries
pobiera tablicę obiektów jak{key:a, value:b}
i zamienia ją w obiekt z odpowiednimi parami klucz / wartość ({a: b}
);Key
iValue
klucze wTags
tablicy musiały być przeliczone na małe;Aby uzyskać więcej informacji, zobacz samouczek i podręcznik jq na https://stedolan.github.io/jq/
źródło
(.Tags | map({Value, Key}) | from_entries) as $tags
, bez konwersji kluczy na małe litery.Inni udzielili ogólnych odpowiedzi na twoje pytanie, które pokazują dobre sposoby parsowania jsona, jednak ja, podobnie jak ty, szukałem sposobu na wyodrębnienie identyfikatora instancji aws za pomocą podstawowego narzędzia, takiego jak awk lub sed, bez zależności od innych pakietów. Aby to osiągnąć, możesz przekazać argument „--output = text” do komendy aws, która da ci łańcuch przetwarzany przez awk. Dzięki temu możesz po prostu uzyskać identyfikator instancji, używając czegoś takiego:
źródło
Jshon jest dostępny w kilku dystrybucjach:
Słabe wyjaśnienie:
-e uu
wyodrębni obiektuu
,-a
sprawi, że tablica będzie użyteczna (nie jestem pewien, czy poprawnie sformułowałem ten, ale w każdym razie…),-u
zdekoduje ciąg,-p
wróci do poprzedniego elementu (wydaje się, że-i N
N jest dowolną liczbą, ma taki sam efekt) .W zależności od przypadku wyniki mogą wymagać dodatkowego leczenia (jak twoje, jak widać).
Jshon
nie wydaje się jednak odporny na zniekształcenie JSON (twoje „Tagi” przecinkami przed zamykającym nawiasem klamrowym spowodują błąd).Ktoś wspomniał o jsawk w innym wątku, ale go nie testowałem.
źródło
Jeśli jest to ograniczone do przypadku użycia AWS podanego powyżej, należy użyć flag --query i --output dla wywołania interfejsu API CLI
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html
źródło
Oto sugestia jednej linijki:
Nie idealnie, ale zadziałałoby, gdybyś go trochę ulepszył.
Zasadniczo używa
pr
do drukowania każdego zestawu wyników według kolumny. Każdy zestaw wyników jest zwracany przez podstawienie procesu, które analizuje plik JSON i zwraca wartości na podstawie klucza.Działa to podobnie, jak opisano w: Biorąc pod uwagę treść klucz-wartość, jak grupować wartości według klucza i sortować według wartości?
źródło
Spójrz na
jtc
narzędzie cli:pozwala na łatwe wydobycie wymaganych informacji z twojego jsona (zakładając, że jest w
file.json
środku, twój JSON musi zostać naprawiony, jest tam kilka dodatkowych przecinków):źródło
jq "." recovery.js | head -n 20
tłumaczy plik Jason na coś, co można readeable:
Teraz powinno być możliwe parsowanie danych za pomocą standardowych narzędzi
źródło