Linuxでいくつかのパラメーターを抽出する必要があるJSON出力があります。
これは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
を使用してこれを行うにはどうすればよいですか およびawk
?
期待される出力:
Instance id Name cost centre Owner
i-1234576 RDS_Machine (us-east-1c) 1234 Jyoti
承認された回答:
ほぼすべてのプログラミング言語でパーサーを利用できることは、データ交換形式としてのJSONの利点の1つです。
JSONパーサーを実装しようとするよりも、jqなどの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"]'
改訂された質問やコメントのすべてに答えるわけではありませんが、以下で十分に始めることができれば幸いです。
STDINからを読み取り、例のoutput[0]の2行目を出力できるRubyスクリプトがあるとします。そのスクリプトは次のようになります:
#!/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に出力するコマンド
1つの方法は、シェルを使用してこれらのツールを組み合わせることです。
echo -e "Instance idtNametcost centretOwner"
for instance in $(list-instances); do
get-json-for-instance $instance | ./ugly-ruby-scriptrb
done
ここで、「インスタンス」配列にさらに多くのアイテムがあるすべてのインスタンスに対して1つのjsonblobを提供する単一のコマンドがあるかもしれません。その場合は、最初の項目を単に使用するのではなく、スクリプトを少し変更して配列を反復処理する必要があります。
結局、この問題を解決する方法は、Unixの多くの問題を解決する方法です。それをより簡単な問題に分解してください。より簡単な問題を解決するためのツールを見つけるか、作成します。これらのツールをシェルまたは他のオペレーティングシステムの機能と組み合わせます。
[0]どこからコストセンターを取得できるかわからないので、作成しました。