क्रमिक रूप से json को पार्स करने के लिए jq का उपयोग करना और कई क्षेत्रों को प्रदर्शित करना


237

मेरे पास यह जसन है

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}

Jq का उपयोग करके मैं पहले और अंतिम नाम को क्रमिक रूप से प्रदर्शित करना चाहूंगा। इस तरह -

Stevie Wonder
Michael Jackson

यह है कि मैं कितनी दूर मिल गया है -

jq '.users[].first, .users[].last'

लेकिन यह प्रदर्शित करता है

"Stevie"
"Michael"
"Wonder"
"Jackson"

निम्नलिखित सूचना दें -

  1. दोहरे उद्धरण जो मुझे नहीं चाहिए।
  2. गाड़ी लौटती है जो मुझे नहीं चाहिए।
  3. यह जुमला है। मेरी क्वेरी पहले सभी नामों को पहले प्रदर्शित करती है, और फिर सभी अंतिम नामों को। हालांकि, मुझे पहली-आखिरी, पहली-आखिरी जोड़ी चाहिए।

जवाबों:



203

आप समवर्ती तारों के अलावा का उपयोग कर सकते हैं ।

स्ट्रिंग्स को एक बड़ी स्ट्रिंग में शामिल होने से जोड़ा जाता है।

jq '.users[] | .first + " " + .last'

ऊपर काम करता है जब दोनों firstऔर lastस्ट्रिंग हैं। यदि आप विभिन्न डेटाटिप्स (संख्या और स्ट्रिंग) निकाल रहे हैं, तो हमें समकक्ष प्रकारों में बदलने की आवश्यकता है। इस सवाल पर समाधान का जिक्र । उदाहरण के लिए।

jq '.users[] | .first + " " + (.number|tostring)'

41
JSON उद्धरण चिह्नों को समाप्त करने के लिए, -r विकल्प के साथ jq, जैसे jq -r '.users [] | .first + "" + .last '
चोटी

4
+1, लेकिन मेरे उपयोग के मामले में, मैं एक ही पंक्ति में दो संख्याओं को प्रारूपित करने का प्रयास कर रहा हूं। यह दृष्टिकोण विफल हो जाता है क्योंकि यह " "किसी संख्या में नहीं जोड़ा जा सकता है । एरिक का जवाब इस मामले के लिए बेहतर परिणाम देता है।
21

9
@ साइनेसो: (.numA|tostring) + " " + (.numB|tostring)काम करना चाहिए। या इसके बजाय स्ट्रिंग प्रक्षेप का उपयोग करें "\(.numA) \(.numB)":।
LS

जब मैंने किया jq '.users[] | .first + " " + .last', यह बहुत अच्छी तरह से काम किया, लेकिन .firstऔर के मूल्य के बीच एक नई रेखा का कारण बना .last। मैं बदल " "करने के लिए "@"और फिर एक किया sed 's/@/ /g'आउटपुट के रूप में "जॉन स्मिथ" प्राप्त करने के लिए उत्पादन पर। कुछ इस तरह से:jq '.users[] | .first + "@" + .last' | sed 's/@/ /g'
ब्लडीज़ॉक


14

हालांकि उपरोक्त दोनों उत्तर अच्छी तरह से काम करते हैं अगर कुंजी, मूल्य तार हैं, तो मुझे एक स्ट्रिंग और पूर्णांक को जोड़ने की स्थिति थी (उपरोक्त अभिव्यक्तियों का उपयोग करके jq त्रुटियाँ)

आवश्यकता: json के नीचे एक url बनाने के लिए

pradeep@seleniumframework>curl http://192.168.99.103:8500/v1/catalog/service/apache-443 | jq .[0]
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   251  100   251    0     0   155k      0 --:--:-- --:--:-- --:--:--  245k
{
  "Node": "myconsul",
  "Address": "192.168.99.103",
  "ServiceID": "4ce41e90ede4:compassionate_wozniak:443",
  "ServiceName": "apache-443",
  "ServiceTags": [],
  "ServiceAddress": "",
  "ServicePort": 1443,
  "ServiceEnableTagOverride": false,
  "CreateIndex": 45,
  "ModifyIndex": 45
}

उपाय:

curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'

ध्यान दें कि समापन कोष्ठक से बचने की जरूरत नहीं है, और गलत होगा।
निमो

2
@ नोइमो: यह बच नहीं रहा है। \(...)स्ट्रिंग प्रक्षेप है। यहां यह संख्यात्मक .ServicePortको स्ट्रिंग में बदल देता है । +इस समाधान को छोटा करने के लिए संकेतों के स्थान पर प्रक्षेप का उपयोग किया जा सकता है ।
LS

12

यह नामों की एक सरणी का उत्पादन करेगा

> jq '[ .users[] | (.first + " " + .last) ]' ~/test.json

[
  "Stevie Wonder",
  "Michael Jackson"
]

4

इस तरह से कुछ करके मैं जो चाहता था, उसके बहुत करीब पहुंच गया

cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | "    - " + .sub_key)' | tr -d '"' 

जिसका उत्पादन मेरे लिए पर्याप्त रूप से यमल के करीब है, आमतौर पर इसे बिना किसी समस्या के अन्य उपकरणों में आयात किया जाता है। (मैं अभी भी इनपुट json के सबसेट निर्यात के लिए एक रास्ता खोज रहा हूँ)


1
मेरे मामले में इस तरह का काम, बस छोड़ देना | टीआर -d ' "' अंत में, और करने के लिए JQ -r विकल्प जोड़ने।
user842479

4

मेरा दृष्टिकोण होगा (आपका json उदाहरण अच्छी तरह से नहीं बना है .. अनुमान केवल एक नमूना है)

jq '.Front[] | [.Name,.Out,.In,.Groups] | join("|")'  front.json  > output.txt

कुछ इस तरह लौटता है

"new.domain.com-80|8.8.8.8|192.168.2.2:80|192.168.3.29:80 192.168.3.30:80"
"new.domain.com -443|8.8.8.8|192.168.2.2:443|192.168.3.29:443 192.168.3.30:443"

और नियमित अभिव्यक्ति के साथ आउटपुट को संक्षिप्त करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.