我有一個 JSON 輸出,需要在 Linux 中從中提取一些參數。
這是 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
}
]
}
我想編寫一個文件,其中包含實例 ID 等標題、名稱等標籤、成本中心、所有者。以及低於 JSON 輸出的某些值。此處給出的輸出只是一個範例。
我該如何使用sed
and來做到這一點awk
?
預期輸出:
Instance id Name cost centre Owner
i-1234576 RDS_Machine (us-east-1c) 1234 Jyoti
答案1
幾乎所有程式語言都提供解析器,這是 JSON 作為資料交換格式的優點之一。
您可能最好使用為 JSON 解析建置的工具,例如傑克或具有 JSON 函式庫的通用腳本語言。
例如,使用 jq,您可以從 Instances 陣列的第一項中提取 ImageID,如下所示:
jq '.Instances[0].ImageId' test.json
或者,要使用 Ruby 的 JSON 函式庫來取得相同的資訊:
ruby -rjson -e 'j = JSON.parse(File.read("test.json")); puts j["Instances"][0]["ImageId"]'
我不會回答您所有修改後的問題和評論,但希望以下內容足以幫助您開始。
假設您有一個 Ruby 腳本,可以從 STDIN 讀取 a 並輸出範例輸出 [0] 中的第二行。該腳本可能類似於:
#!/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}"
您如何使用這樣的腳本來實現您的整個目標?好吧,假設您已經擁有以下內容:
- 列出所有實例的命令
- 用於取得清單中任何實例的上述 json 並將其輸出到 STDOU 的命令
一種方法是使用 shell 來組合這些工具:
echo -e "Instance id\tName\tcost centre\tOwner"
for instance in $(list-instances); do
get-json-for-instance $instance | ./ugly-ruby-scriptrb
done
現在,也許您有一個命令可以為所有實例提供一個 json blob,並且在「實例」陣列中包含更多項目。好吧,如果是這種情況,您只需要稍微修改腳本即可迭代數組,而不是簡單地使用第一項。
最後解決這個問題的方法,就是解決Unix很多問題的方法。將其分解為更簡單的問題。尋找或編寫工具來解決更簡單的問題。將這些工具與您的 shell 或其他作業系統功能結合。
[0] 請注意,我不知道你從哪裡得到成本中心,所以我只是編造出來的。
答案2
您可以使用以下 python 腳本來解析該資料。假設您有來自array1.json
、array2.json
等文件中數組的 JSON 資料。
import json
import sys
from pprint import pprint
jdata = open(sys.argv[1])
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()
然後運行:
$ for x in `ls *.json`; do python parse.py $x; done
InstanceId - Name - Owner
i-1234576 - RDS_Machine (us-east-1c) - Jyoti Bhanot
我沒有在您的數據中看到成本,這就是為什麼我沒有將其包括在內。
根據評論中的討論,我更新了 parse.py 腳本:
import json
import sys
from pprint import pprint
jdata = sys.stdin.read()
data = json.loads(jdata)
print "InstanceId", " - ", "Name", " - ", "Owner"
print data["Instances"][0]["InstanceId"], " - " ,data["Instances"][0]["Tags"][1]["Value"], " - " ,data["Instances"][0]["Tags"][2]["Value"]
您可以嘗試執行以下命令:
#ec2-describe-instance <instance> | python parse.py
答案3
其他人已經為您的問題提供了一般答案,這些答案展示了解析json 的好方法,但是我和您一樣,正在尋找一種使用awk 或sed 等核心工具來提取aws 實例id 的方法,而不依賴於其他包。要實現此目的,您可以將「--output=text」參數傳遞給 aws 命令,這將為您提供 awk 可解析字串。這樣,您就可以使用類似以下內容的方式簡單地取得實例 ID...
aws ec2 run-instances --output text | awk -F"\t" '$1=="INSTANCES" {print $8}'
答案4
如果這僅限於上面提供的 AWS 使用案例,您應該為 CLI API 呼叫使用 --query 和 --output 標誌
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html