লিনাক্সে শেল স্ক্রিপ্টিং দিয়ে কীভাবে JSON পার্স করবেন?


56

আমার একটি জেএসএন আউটপুট রয়েছে যা থেকে আমার লিনাক্সে কয়েকটি পরামিতি বের করতে হবে।

এটি 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
            }
        ]
    }

আমি এমন একটি ফাইল লিখতে চাই যাতে উদাহরণ আইডি, ট্যাগের মতো ট্যাগ, ব্যয় কেন্দ্র, মালিকের মতো শিরোনাম থাকে। এবং JSON আউটপুট থেকে নির্দিষ্ট মান নীচে। এখানে প্রদত্ত আউটপুট কেবল একটি উদাহরণ।

আমি কীভাবে এটি ব্যবহার করে sedএবং করতে পারি awk?

প্রত্যাশিত আউটপুট:

 Instance id         Name                           cost centre             Owner
    i-1234576          RDS_Machine (us-east-1c)        1234                   Jyoti

1
আপনার সি এল এল কলটি অজগরে পাইপ করুন, প্রস্তাবিত কারণ এটি ইসি 2 উদাহরণগুলির স্থানীয়। পাইথন সহজেই JSON ব্যাখ্যা করতে পারে। উদাহরণের জন্য নীচের উত্তরটি দেখুন। অবশ্যই, আপনি অন্য কোনও এসএস ভাষা ব্যবহার করতে পারেন তবে পাইথন ইতিমধ্যে সেখানে থাকার জন্য তাদের ইনস্টলসের প্রয়োজন হবে।
রবি অ্যাভারিল

উত্তর:


65

ডেটা-ইন্টারচেঞ্জ ফর্ম্যাট হিসাবে প্রায় প্রতিটি প্রোগ্রামিং ভাষায় পার্সারগুলির উপলভ্যতা JSON এর অন্যতম সুবিধা।

জেএসএন পার্সার প্রয়োগের চেষ্টা করার পরিবর্তে, আপনি সম্ভবত JSON পার্সিংয়ের জন্য তৈরি একটি সরঞ্জাম যেমন জেকিউ বা জেনসন লাইব্রেরি সহ সাধারণ উদ্দেশ্যে স্ক্রিপ্ট ভাষা ব্যবহার করে আরও ভাল ব্যবহার করতে পারেন ।

উদাহরণস্বরূপ, জেকিউ ব্যবহার করে, আপনি উদাহরণস্বরূপ অ্যারের প্রথম আইটেম থেকে চিত্রটি আইডিআইডি টেনে আনতে পারেন:

jq '.Instances[0].ImageId' test.json

বিকল্পভাবে, রুবির জেএসএন লাইব্রেরি ব্যবহার করে একই তথ্য পেতে:

ruby -rjson -e 'j = JSON.parse(File.read("test.json")); puts j["Instances"][0]["ImageId"]'

আমি আপনার সমস্ত সংশোধিত প্রশ্ন এবং মন্তব্যের উত্তর দেব না তবে নিম্নলিখিতটি আপনাকে শুরু করার পক্ষে যথেষ্ট।

মনে করুন যে আপনার কাছে একটি রুবি স্ক্রিপ্ট রয়েছে যা STDIN থেকে একটি পড়তে পারে এবং আপনার উদাহরণ আউটপুট [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}"

আপনি কীভাবে আপনার পুরো লক্ষ্যটি সম্পাদন করতে এই জাতীয় স্ক্রিপ্ট ব্যবহার করতে পারেন? ঠিক আছে, ধরুন আপনার ইতিমধ্যে নিম্নলিখিতগুলি রয়েছে:

  • আপনার সমস্ত দৃষ্টান্ত তালিকাবদ্ধ করার জন্য একটি কমান্ড
  • আপনার তালিকার উপরে যে কোনও উদাহরণের জন্য উপরে জসনকে পাওয়ার জন্য একটি কমান্ড এবং এটি STDOU এ আউটপুট করুন

একটি উপায় এই সরঞ্জামগুলি একত্রিত করতে আপনার শেল ব্যবহার করা হবে:

echo -e "Instance id\tName\tcost centre\tOwner"
for instance in $(list-instances); do
    get-json-for-instance $instance | ./ugly-ruby-scriptrb
done

এখন, আপনার কাছে সম্ভবত একটি একক কমান্ড রয়েছে যা আপনাকে "ইনস্ট্যান্স" অ্যারেতে আরও আইটেম সহ সমস্ত দৃষ্টান্তের জন্য একটি জসন ব্লব দেয়। ঠিক আছে, যদি এটি হয় তবে আপনাকে প্রথম আইটেমটি ব্যবহার না করে অ্যারের মাধ্যমে পুনরাবৃত্তি করতে স্ক্রিপ্টটি কিছুটা পরিবর্তন করতে হবে।

শেষ পর্যন্ত, এই সমস্যাটি সমাধান করার উপায়, ইউনিক্সে বহু সমস্যা সমাধানের উপায়। এটিকে সহজ সমস্যায় ভেঙে দিন। সহজ সমস্যা সমাধানের জন্য সরঞ্জামগুলি সন্ধান করুন বা লিখুন। আপনার শেল বা অন্যান্য অপারেটিং সিস্টেমের বৈশিষ্ট্যগুলির সাথে সেই সরঞ্জামগুলি একত্রিত করুন।

[0] নোট করুন যে আপনি কোথা থেকে ব্যয়-কেন্দ্র পেয়েছেন আমার কোনও ধারণা নেই, তাই আমি এটি তৈরি করেছি।


আমি আমার মেশিনে জিকিউ ইনস্টল করেছি। তবে আমি কীভাবে তথ্য পেতে জানি না। আমি প্রশ্নটি আপডেট করছি
ব্যবহারকারী 3086014

কিভাবে যে কি. কমান্ড ec2- বর্ণন উদাহরণটি এর মতো পুনরায় সংস্থান দেয়। এটি 1 উদাহরণের জন্য ডেটা, 100 টি উদাহরণ রয়েছে। স্ক্রিপ্টে এটি কীভাবে করবেন
ব্যবহারকারী 3086014

আমার কাছে ক্লাব সরঞ্জাম রয়েছে যা আমাকে আউটপুট দেয়। এখন কীভাবে আউটপুট এবং প্রয়োজনীয় ট্যাগগুলি পার্স করতে হবে যা আমি সত্যিই জানি না
ব্যবহারকারী 3086014

2
@ ব্যবহারকারী 3086014 আমি দুঃখিত, তবে আমি এই উত্তরটিতে আরও কাজ করব না। আমার সেখানে থাকা রুবির উদাহরণটি একবার দেখুন। আপনি চান JSON এর বিভিন্ন অংশ থেকে কীভাবে ট্যাগ পাবেন তা শুরু করার জন্য এটি আপনাকে একটি ভাল জায়গা দেওয়া উচিত।
স্টিভেন ডি

জসন সরঞ্জামগুলির বিস্তৃতিতে উপলব্ধ জেকিউ আমার প্রিয় স্টেডোলান . github.io/jq/manual । এসটিডি বিতরণেও পাওয়া যায়। পরীক্ষামূলক ফিল্টারের একটি খেলার মাঠ পাওয়া যাবে jqplay.org/jq?q=.&j=%22Hello%2C%20world!%22
lrkwz

15

আপনি সেই ডেটা পার্স করতে নিম্নলিখিত পাইথন স্ক্রিপ্ট ব্যবহার করতে পারেন। অনুমান করতে দেয় আপনার মত ফাইল বিন্যাসগুলি থেকে JSON তথ্য আছে array1.json, array2.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

আমি আপনার ডেটাতে ব্যয় দেখিনি, সে কারণেই আমি এটি অন্তর্ভুক্ত করিনি।

মন্তব্যে আলোচনা অনুযায়ী, আমি পার্স.পি স্ক্রিপ্ট আপডেট করেছি:

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

কমান্ড দ্বারা ফিরে আসা একই অ্যারে আছে এটি কেবল একটি অ্যারে। এটি কীভাবে করবেন
ব্যবহারকারী 3086014

এবং এই ডেটাটি রানটাইমের সময় ec2- বর্ণনা উদাহরণ কমান্ড দ্বারা উত্পন্ন হয়। কীভাবে এটি পরিচালনা করবেন
ব্যবহারকারী 3086014

আমি এই অজগর স্ক্রিপ্টটি কিছুটা পরিবর্তন করেছি: 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() আপনার কাছে অ্যারে থেকে সমস্ত জেসন ডেটা যদি অ্যারে 1.json, অ্যারে 2.জসন, ... এবং এর মতো ফাইলগুলিতে থাকে তবে আপনি এটি চালানোর চেষ্টা করতে পারেন: # for x in ls * .json; do python parse.py $x; done
রবার্ট জোনজি

আপনি উত্তরটি নিজেই আপডেট করতে পারেন। এটি পঠনযোগ্য নয়
ব্যবহারকারী 3086014

এছাড়াও আমার কাছে অ্যারেগুলির 100 টি অ্যারে রয়েছে
ব্যবহারকারী 3086014

9

নিম্নলিখিত জেকি কোড:

.Instances[] | (.Tags | map(.value=.Value | .key=.Key) | from_entries) as $tags | "\(.InstanceId) | \($tags.Name) | \($tags["cost.centre"]) | \($tags.Owner)"

ব্যবহৃত:

json_producer | jq -r '<jq code...>'

আউটপুট হবে:

i-1234576 | RDS_Machine (us-east-1c) | 1234 | Jyoti Bhanot

কোডটি বোঝার জন্য কয়েকটি পয়েন্টার:

  • from_entriesএর মতো বস্তুর অ্যারে নেয় {key:a, value:b}এবং এটিকে সংশ্লিষ্ট কী / মান জোড় ( {a: b}) সহ কোনও বস্তুতে পরিণত করে ;
  • অ্যারেতে থাকা Keyএবং Valueকীগুলি Tagsছোট হাতের অক্ষরে রূপান্তর করতে হয়েছিল;
  • শেষ স্ট্রিংটিতে জেকির স্ট্রিং ইন্টারপোলেশন বৈশিষ্ট্য ব্যবহার করা হয়েছে। আপনি এটি প্রয়োজন হিসাবে টুইট করতে পারেন।

আরও বিশদ বিবরণের জন্য, https://stedolan.github.io/jq/ এ জিকিউর টিউটোরিয়াল এবং ম্যানুয়ালটি দেখুন


1
আপনি এখন ছোট (.Tags | map({Value, Key}) | from_entries) as $tagsঅক্ষরে কীগুলিতে রূপান্তর না করে ব্যবহার করে ট্যাগের নিষ্কাশনটি ছোট করতে পারেন ten
mloughran

8

অন্যরা আপনার প্রশ্নের সাধারণ উত্তর সরবরাহ করেছে যা জেএসনকে পার্স করার ভাল উপায়গুলি দেখায় তবে আমি, আপনার মতো অন্যান্য প্যাকেজের উপর নির্ভর না করে অ্যাডাব্ল্যাড বা সিডের মতো একটি মূল সরঞ্জাম ব্যবহার করে একটি অ্যাউজেন্স আইডি বের করার উপায় খুঁজছিলাম। এটি সম্পাদন করতে আপনি "আউটপুট = পাঠ্য" আর্গুমেন্টটি আপনার আউজ কমান্ডের সাথে পাস করতে পারেন যা আপনাকে একটি বিশ্রী পার্সেবল স্ট্রিং দেয়। এটির সাহায্যে আপনি নীচের মতো কিছু ব্যবহার করে ইনস্ট্যান্স আইডি পেতে পারেন ...

aws ec2 run-instances --output text  | awk -F"\t" '$1=="INSTANCES" {print $8}'

3

জশন বিভিন্ন বিতরণে উপলব্ধ:

$ echo your_JSON|jshon -e Instances -a -e InstanceId -u -p -e Tags -a -e Key -u -p -e Value -u
i-1234576
Description
Server for testing RDS feature in us-east-1c AZ
Name
RDS_Machine (us-east-1c)
cost.centre
1234
Owner
Jyoti Bhanot

দরিদ্র ব্যাখ্যা: -e uuঅবজেক্ট উত্থিত করব uu, -aঅ্যারের ব্যবস্থা গ্রহণ করব (নিশ্চিত না আমি সঠিকভাবে এই এক শব্দে কিন্তু যাহাই হউক না কেন ...), -uস্ট্রিং ডিকোড করবে -pপূর্ববর্তী আইটেমে ফিরে যাব (মনে হচ্ছে যে -i N, এন কোন সংখ্যা হচ্ছে, একই প্রভাব রয়েছে) ।

আপনার কেসের উপর নির্ভর করে আউটপুটটির জন্য কিছু পোস্ট-ট্রিটমেন্টের প্রয়োজন হতে পারে (আপনার মতো, আপনি দেখতে পারেন)।

Jshon জেএসএন দূষিততার বিরুদ্ধে শক্তিশালী বলে মনে হচ্ছে না, যদিও (ক্লোজিং কোঁকড়া বন্ধনীর আগে কমা দিয়ে আপনার "ট্যাগস" ত্রুটি বাড়িয়ে তুলবে)।

কেউ অন্য থ্রেডে জাসউকের কথা উল্লেখ করেছেন , তবে আমি এটি পরীক্ষা করে দেখিনি।



0

এখানে ওয়ান-লাইনারের পরামর্শ দেওয়া হল:

pr -mt \
 <(grep -o ".*: .*," in.json | grep -iw InstanceId | cut -d: -f2) \
 <(grep -o ".*: .*," in.json | grep -iw Value      | cut -d: -f2) \
 <(grep -o ".*: .*," in.json | grep -iw Key        | cut -d: -f2)

নিখুঁত নয়, তবে আপনি যদি এটি কিছুটা টুইট করেন তবে এটি কাজ করবে।

এটি মূলত prপ্রতি কলামে প্রতিটি সেট ফলাফল মুদ্রণ করে ব্যবহার করে । প্রতিটি ফলাফল সেট প্রক্রিয়া প্রতিস্থাপনের মাধ্যমে ফিরে আসে যা জেএসওএন ফাইলকে বিশ্লেষণ করে এবং কীটির উপর ভিত্তি করে মানগুলি ফেরত দেয়।

এটি বর্ণিত হিসাবে একইভাবে কাজ করে: কী-মান সামগ্রী দেওয়া হয়েছে, কীভাবে আমি কী দ্বারা মানগুলিকে গ্রুপ করব এবং মান অনুসারে বাছাই করব?


0

jtcক্লাইপ সরঞ্জামটি একবার দেখুন :

এটি সহজেই আপনার জেসন থেকে প্রয়োজনীয় তথ্য বের করতে দেয় (এটি বিটিডব্লুতে ধরে file.jsonনিলে, আপনার জেএসওএন স্থির করা দরকার, সেখানে বেশ কয়েকটি অতিরিক্ত কমা রয়েছে):

bash $ cat file.json | jtc -x '<InstanceId>l+0[-1]' -y '[InstanceId]' -y "[Key]:<Name>[-1][Value]" -y "[Key]:<cost.centre>[-1][Value]" -y "[Key]:<Owner>[-1][Value]" | sed 's/"/\\"/g' | xargs -L4 echo
"i-1234576" "RDS_Machine (us-east-1c)" "1234" "Jyoti Bhanot"
bash $ 

-2

jq "." recovery.js | head -n 20

আপনার জেসন ফাইলটি এমন পাঠযোগ্য কিছুতে অনুবাদ করে:

{
  "সংস্করণ": [
    "Sessionrestore",
    1
  ],
  "উইন্ডোজ": [
    {
      "ট্যাব": [
        {
          "এন্ট্রি": [
            {
              "url": "http://orf.at/#/stories/2.../",
              "শিরোনাম": "নিউজ.অরএফ.এ্যাট",
              "চরসেট": "ইউটিএফ -8",
              "আইডি": 9588,
              "ডকশেলআইডি": 298,
              "docIdentifier": 10062,
              "জেদ": সত্য
            },
...

এখন কোনও মানক সরঞ্জাম দিয়ে আপনার ডেটা পার্স করা সম্ভব হওয়া উচিত

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.