GNU/Linux >> Linux の 問題 >  >> Linux

Linuxでシェルスクリプトを使用してJsonを解析する方法は?

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に出力するコマンド
関連:Linux – Unix / Linux:文字列を含むファイルを再帰的に検索しますか?

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]どこからコストセンターを取得できるかわからないので、作成しました。


Linux
  1. libvirtでVagrantを使用する方法

  2. Linux シェルを使用してスペースを含むファイルの名前を変更するにはどうすればよいですか?

  3. Linux はシェル スクリプトをどのように処理しますか?

  1. Linuxでgocryptfsを使用してファイルを暗号化する方法

  2. Linuxの基本:Wgetを使用してシェルにファイルをダウンロードする方法

  3. Linuxコマンドラインツールを使用してJSONを解析してきれいに印刷する方法

  1. Linuxでシェルを変更する方法

  2. Linuxシェルスクリプトでファイル内の単語を変更する方法

  3. Linuxシェルで変数を使用して除算を行うにはどうすればよいですか?