JSON অ্যারে থেকে একটি ক্ষেত্রকে ব্যাশ অ্যারে পার্স করুন


14

আমার কাছে একটি জেএসএন আউটপুট রয়েছে যা ভেরিয়েবলে সঞ্চিত অবজেক্টগুলির একটি তালিকা রয়েছে। (আমি সম্ভবত এই শব্দটি উচ্চারণ করছি না)

[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

উবুন্টু 14.04.1 এ চালানোর জন্য ব্যাশ স্ক্রিপ্টের জন্য অ্যারেতে আইটেম 2 এর জন্য আমার সমস্ত মান দরকার।

পুরো ফলাফলটিকে অ্যারেতে আনার জন্য আমি বেশ কয়েকটি উপায় খুঁজে পেয়েছি তবে কেবল আমার প্রয়োজনীয় আইটেমগুলি নয়

উত্তর:


18

ব্যবহার :

$ cat json
[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

কোড:

arr=( $(jq -r '.[].item2' json) )
printf '%s\n' "${arr[@]}"

আউটপুট:

value2
value2_2

কোনও ফাইলের পরিবর্তে ভেরিয়েবল থেকে এটি করা সম্ভব? আমি প্রয়োজন না হলে অতিরিক্ত ফাইল সিস্টেম অ্যাক্সেস এড়ানোর চেষ্টা করি। আমি একবার এই অ্যারে টানলে আমি জসন আউটপুট দিয়ে এসেছি।
— জেপেটনডব্লিউপিডি

1
আপনি কিছু চেষ্টা করেছেন?
— গিলস কুইনট

2
jq . <<< "$json"এটি শেল (বাশ) সম্পর্কিত, এর সাথে নির্দিষ্ট নয়jq
— গিলস কুইনট

1
অনুপস্থিত বন্ধনী:arr=( $(...) )
— গিলস কুইনট

4
দুর্দান্ত jqকমান্ড, তবে দয়া করে কমান্ড আউটপুটটিকে একটি অ্যারেতে পার্স করবেন না arr=( $(...) )(যদিও এটি নমুনা ইনপুট নিয়ে কাজ করে): এটি এম্বেড করা বা শীর্ষস্থানীয় / পিছনের সাদা স্থানের সাথে অভিযুক্ত হিসাবে কাজ করে না এবং এর ফলে দুর্ঘটনাক্রমে গ্লোব্বিং হতে পারে।
— mklement0

5

নিম্নলিখিতটি আসলে বগি:

# BAD: Output line of * is replaced with list of local files; can't deal with whitespace
arr=( $( curl -k "$url" | jq -r '.[].item2' ) )

পরিবর্তে, ব্যবহার করুন:

# GOOD (with bash 4.x+), but can't detect failure
readarray -t arr < <(curl -k "$url" | jq -r '.[].item2' )

... বা, আরও ভাল ...

# GOOD (with bash 3.x+), *and* has nonzero status if curl or jq fails
IFS=$'\n' read -r -d '' -a arr \
  < <(set -o pipefail; curl --fail -k "$url" | jq -r '.[].item2' && printf '\0')

2

স্পুতনিককে ধন্যবাদ আমি এটি পেয়েছি:

arr=( $(curl -k https://localhost/api | jq -r '.[].item2') )

আমার কাছে থাকা JSON হ'ল একটি এপিআই থেকে আউটপুট। আমার যা করতে হবে তা কেবল ফাইল আর্গুমেন্টটি সরিয়ে এবং |কার্লের আউটপুটটি জিকিউতে পাইপ করে। দুর্দান্ত কাজ করে এবং কিছু পদক্ষেপ সংরক্ষণ করে।


এই কোডটি আসলে কিছুটা বগি। আপনার ফলাফলের উপাদান থাকলে কী হয় তা দেখুন *- এটি আপনার বর্তমান ডিরেক্টরিতে ফাইলগুলির একটি তালিকা দিয়ে প্রতিস্থাপিত হবে।
— চার্লস ডাফি

1
একইভাবে, এতে item2শ্বেতস্পেসের সাথে মানটি একাধিক অ্যারের উপাদানে পরিণত হবে।
— চার্লস ডাফি

0

একটি সহজ বিকল্প হিসাবে, jtcসরঞ্জামটি দেখুন ( https://github.com/ldn-softdev/jtc এ ), একই জিনিস অর্জনের জন্য (জেউ এর উদাহরণ হিসাবে):

bash $ arr=( $(jtc -w '<item2>l+0' file.json) )
bash $ printf '%s\n' "${arr[@]}"
"value2"
"value2_2"
bash $ 

-wবিকল্পের ব্যাখ্যা : কৌণিক বন্ধনী <...>অনুসন্ধান পুরো জেসনকে নির্দিষ্ট করে, প্রত্যয়টি lমানগুলির চেয়ে অনুসন্ধানের লেবেলগুলিকে +0নির্দেশ দেয় , সমস্ত ঘটনা সন্ধানের নির্দেশ দেয় (কেবলমাত্র প্রথমটি নয়)।


সমস্ত arr=( $(jq ...) )উত্তর হিসাবে একই বাগ , বিষয়বস্তু হিসাবে insofar অ্যারে পপুলেট করার জন্য স্ট্রিং-বিভক্ত এবং গ্লোব-প্রসারিত হচ্ছে - যার অর্থ স্থানগুলি (কেবল নিউলাইন নয়) নতুন উপাদান তৈরি করে, এবং গ্লোব এক্সপ্রেশনের মতো দেখতে এমন উপাদানগুলি ফাইল দ্বারা প্রতিস্থাপন করা হয় যা অভিব্যক্তি মেলে।
— চার্লস ডাফি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.