एक क्षेत्र JSON सरणी से bash सरणी में पार्स करें


14

मेरे पास एक JSON आउटपुट है जिसमें एक चर में संग्रहीत वस्तुओं की एक सूची है। (मैं सही नहीं हो सकता है)

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

मुझे ubuntu 14.04.1 पर चलाने के लिए एक bash स्क्रिप्ट के लिए एक सरणी में Item2 के लिए सभी मानों की आवश्यकता है।

मैंने पूरे परिणाम को एक सरणी में प्राप्त करने के तरीकों का एक गुच्छा पाया है, लेकिन न केवल उन वस्तुओं पर जो मुझे चाहिए

जवाबों:


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

क्या फ़ाइल के बजाय एक चर से ऐसा करना संभव है? अगर मुझे इसकी आवश्यकता नहीं है, तो मैं अतिरिक्त फाइल सिस्टम एक्सेस से बचने की कोशिश करता हूं। एक बार जब मैं इस सरणी को खींचता हूं तो मुझे json आउटपुट के साथ किया जाता है।
जपटनडब्ल्यूपीडी

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 मेरे पास एक एपीआई से आउटपुट है। मैं सभी की जरूरत है wans फ़ाइल तर्क को हटाने और |कर्ल के उत्पादन को jq तक पाइप करता है। बढ़िया काम किया और कुछ कदम बचाए।


यह कोड वास्तव में थोड़ा छोटा है। यदि आपके पास परिणाम तत्व है तो क्या होता है, *इसे देखें - यह आपकी वर्तमान निर्देशिका में फ़ाइलों की सूची के साथ बदल जाएगा।
चार्ल्स डफी

1
इसी तरह, item2इसमें व्हाट्सएप के साथ एक मान एक से अधिक एलीमेंट तत्व बन जाएगा।
चार्ल्स डफी

0

एक आसान विकल्प के रूप में, उसी चीज़ को प्राप्त करने के लिए jtcटूल ( https://github.com/ldn-softdev/jtc पर ) देखें, (जैसा कि jq के उदाहरण में):

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

-wविकल्प पर स्पष्टीकरण : कोणीय कोष्ठक <...>खोज पूरे जौन को निर्दिष्ट करते हैं, प्रत्यय lमानों के बजाय खोज लेबल +0को निर्देश देते हैं, सभी घटनाओं (केवल पहले एक के बजाय) को खोजने का निर्देश देते हैं।


सभी arr=( $(jq ...) )उत्तरों के रूप में समान बग , सामग्री को स्ट्रिंग-स्प्लिट और ग्लोब के रूप में विस्तारित किया जा रहा है ताकि सरणी को पॉप्युलेट करने के लिए विस्तार किया जा सके - अर्थ रिक्त स्थान (न सिर्फ नईलाइन) नए तत्व बनाते हैं, और एक ग्लोब एक्सप्रेशन की तरह दिखने वाले तत्वों को फाइलों द्वारा प्रतिस्थापित किया जाता है अभिव्यक्ति मेल खाती है।
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.