JSON फ़ाइल से डेटा कैसे निकालें


13

मेरे पास मेरे प्रश्न के लिए एक समाधान खोजने के लिए है, लेकिन एक या बेहतर नहीं मिला मैंने कहा कि मुझे वह नहीं मिला जो मैंने पाया। तो चलो मेरी समस्या के बारे में बात करते हैं। मैं एक रास्पबेरी पाई पर एक स्मार्ट होम कंट्रोल सॉफ्टवेयर का उपयोग कर रहा हूं और जैसा कि मैंने इस सप्ताह के अंत में पाया कि मैं अपने आउटडोर तापमान सेंसर से डेटा प्राप्त कर सकता हूं। पायलट-प्राप्त का उत्पादन इस तरह दिखता है:

{
        "message": {
                "id": 4095,
                "temperature": 409.5
        },
        "origin": "receiver",
        "protocol": "alecto_wsd17",
        "uuid": "0000-b8-27-eb-0f3db7",
        "repeats": 3
}
{
        "message": {
                "id": 1490,
                "temperature": 25.1,
                "humidity": 40.0,
                "battery": 1
        },
        "origin": "receiver",
        "protocol": "alecto_ws1700",
        "uuid": "0000-b8-27-eb-0f3db7",
        "repeats": 3
}
{
        "message": {
                "id": 2039,
                "temperature": 409.5
        },
        "origin": "receiver",
        "protocol": "alecto_wsd17",
        "uuid": "0000-b8-27-eb-0f3db7",
        "repeats": 4
}

अब आपसे मेरा सवाल: मैं 1490 पर जहां तापमान 1490 है, वहां से मैं कैसे तापमान और आर्द्रता निकाल सकता हूं। और आप मुझे बार-बार जांच करने की सलाह कैसे देंगे? प्रत्येक 10 मिनट चलने वाली क्रॉन जॉब द्वारा, पाइलट-प्राप्त का एक आउटपुट बनाता है, आउटपुट का डेटा निकालता है और इसे स्मार्ट होम कंट्रोल एपी में धकेलता है।

किसी को एक विचार है - बहुत बहुत धन्यवाद


3
प्रारूप JSON लगता है । JSON को पार्स करने के बहुत सारे तरीके हैं। यह इस बात पर निर्भर करता है कि आप किस चीज के साथ सहज हैं। अजगर? जावास्क्रिप्ट? कुछ और?
मूरू

मैं अजगर का एक सा और जावास्क्रिप्ट का एक सा पता है ज्यादातर मैं C ++ और C # जानता हूं। लेकिन सभी awk और sed कमांड को देखने के बाद मुझे कुछ आसान कमांड xD होने चाहिए
राउल गार्सिया सांचेज़

1
यह मुश्किल नहीं है awkऔर sedबशर्ते JSON आउटपुट यहां दिखाए गए स्वरूपण को बनाए रखता है, जिसकी आवश्यकता नहीं है - JSON के लिए व्हॉट्सएप कोई मायने नहीं रखता है। उदाहरण के लिए, यह awkकमांड: awk '/temperature|humidity/ {print $2}'करीब है।
मूरू

4
ksh93जौन पार्सिंग के साथ बनाया गया है read
15

1
wheezy-backports की जाँच करें। यह वहाँ हो सकता है, आपको जेसी में अपग्रेड करने से बचाता है (जब तक आप किसी भी तरह अपग्रेड करने की योजना नहीं बना रहे थे)। अहा! यह घरघराहट के लिए है। package.debian.org/wheezy-backports/jq
cas

जवाबों:


23

आप jqशेल में json फ़ाइलों को प्रोसेस करने के लिए उपयोग कर सकते हैं ।

उदाहरण के लिए, मैंने आपकी नमूना json फ़ाइल को सहेजा raul.jsonऔर फिर भाग गया:

$ jq .message.temperature raul.json 
409.5
25.1
409.5
$ jq .message.humidity raul.json 
null
40
null

jq सबसे linux distros के लिए प्री-पैकेज्ड उपलब्ध है।

संभवत: इसे jqअपने आप में करने का एक तरीका है, लेकिन मुझे एक लाइन पर दोनों वांछित मूल्यों को प्राप्त करने का सबसे सरल तरीका है xargs। उदाहरण के लिए:

$ jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json | xargs
25.1 40

या, यदि आप प्रत्येक .message.idउदाहरण के माध्यम से लूप करना चाहते हैं, तो हम .message.idआउटपुट में जोड़ सकते हैं और उपयोग कर सकते हैं xargs -n 3क्योंकि हम जानते हैं कि तीन फ़ील्ड होंगे (आईडी, तापमान, आर्द्रता):

jq '.message.id, .message.temperature, .message.humidity' raul.json | xargs -n 3
4095 409.5 null
1490 25.1 40
2039 409.5 null

फिर आप उस आउटपुट को पोस्ट-प्रोसेस कर सकते हैं जो awk या जो भी हो।


अंत में, अजगर और पर्ल दोनों के पास जर्स डेटा को पार्स करने और हेरफेर करने के लिए उत्कृष्ट पुस्तकालय हैं। जैसा कि php और java सहित कई अन्य भाषाएं करती हैं।


2
विशेष रूप से,jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json
ग्लेन जैकमैन

1
या, बैश में,{ read temp; read hum; } < <(jq ...)
ग्लेन जैकमैन

1
मेरा जवाब देखें जो बस का उपयोग करता है grep। यह कुछ विशिष्ट संस्करणों के लिए काम नहीं कर सकता है grep, लेकिन यह jqइस परिदृश्य की तुलना में अधिक सीधा है, भले ही jqविशेष रूप से JSON को पार्स करने के लिए डिज़ाइन किया गया हो। मैंने jqउत्तर को एक अपवित्र रूप दिया, फिर चाहे वह कोई भी हो। यह वास्तव में नौकरी के लिए एक उपकरण है, लेकिन कभी-कभी आप स्टेपल-रिमूवर की तलाश करने के बजाय बस अपनी उंगलियों से स्टेपल को हटा सकते हैं।
रुबिनोरेल्स

2
json को नियमित रूप से एक्सएमएल या html कैन से अधिक किसी भी नियमित अभिव्यक्ति के साथ पारिश्रमिक नहीं दिया जा सकता है। और सबसे जोंस डेटा (जैसे एक वेब एपीआई के माध्यम से प्राप्त) अतिरिक्त लाइन-फीड और इंडेंटेशन के साथ अच्छी तरह से स्वरूपित नहीं होता है। json को मज़बूती से पार्स करने के लिए, आपको json parser की आवश्यकता होती है। jqशेल स्क्रिप्ट के लिए ऐसा ही एक है। अन्य भाषाओं में लायर्स पार्सिंग लाइब्रेरी हैं।
कैस

1
कुछ भी नियमित अभिव्यक्ति के साथ मज़बूती से पार्स किया जा सकता है। यह सिर्फ इस बात पर निर्भर करता है कि आप कितने का उपयोग करते हैं। आपको कैसे लगता jqहै कि यह क्या करता है?
mikeserv

0

jqअब तक का सबसे सुरुचिपूर्ण समाधान है। awkआप के साथ लिख सकता है

awk -v id=1490 '
    $1 == "\"id\":" && $2 == id"," {matched = 1}
    $1 == "}," {matched = 0}
    matched && $1 ~ /temperature|humidity/ {sub(/,/,"", $2); print $2}
' file

0

उन लोगों के लिए जो उन्नत awkरूप में अच्छी तरह से नहीं समझते हैं, जैसे वे (जैसे कि मेरे जैसे लोग) और jqपूर्व-स्थापित नहीं हैं , एक आसान समाधान एक साथ देशी आदेशों के एक जोड़े को पाइपिंग करना होगा:

grep -A2 '"id": 1490,' stats.json | sed '/1490/d;s/"//g;s/,//;s/\s*//'

आप केवल मूल्यों को प्राप्त करने की कोशिश कर रहे हैं, यह आसान बस का उपयोग कर grepके बजाय awkया sed:

grep -A2 '"id": 1490,' stats.json | grep -o "[0-9]*\.[0-9]*"

स्पष्टीकरण प्रदान करने के लिए, यह मेरे लिए सबसे सरल तरीका है।

  • grep -A2लाइन आप निम्नलिखित 2 लाइनों, जो तापमान और आर्द्रता के साथ शामिल JSON में तलाश कर रहे हैं पकड़ लेता है।
  • पाइप grep -oकेवल एक अंक द्वारा अलग किए गए केवल संख्यात्मक अंकों को प्रिंट करता है .(जो पहली 1490पंक्ति में कभी नहीं होगा , इसलिए आपको अपने 2 मूल्यों - तापमान और आर्द्रता के साथ छोड़ दिया जाता है। बहुत ही सरल। उपयोग करने से भी सरल jq, मेरी राय में।

0

कमांड लाइन पर JSON के प्रसंस्करण के लिए मेरी पसंद का उपकरण jq है। हालाँकि, अगर आपने jq स्थापित नहीं किया है तो आप पर्ल के साथ बहुत अच्छा कर सकते हैं:

# perl -MJSON -e '$/ = undef; my $data = <>; for my $hash (new JSON->incr_parse($data)) { my $msg = $hash->{message}; print "$msg->{temperature} $msg->{humidity}\n" if $msg->{id} == 1490 }' < data.json
25.1 40

0

आपका आउटपुट संपूर्ण JSON के बजाय JSON स्निपेट का एक सेट है। यदि आप एक बार अपने आउटपुट को एक इंटीग्रल JSON होने के लिए पुनर्व्यवस्थित करते हैं, जैसे कि (इस तरह आपका आउटपुट चालू होना file.json):

echo "[ $(cat file.json | sed -E 's/^}$/},/; $d') }]"

तब आप jtcउपकरण के साथ जो चाहते हैं उसे प्राप्त करना आसान है ( https://github.com/ldn-softdev/jtc पर उपलब्ध ):

bash $ echo "[ $(cat file.json | sed -E 's/^}$/},/; $d') }]" | jtc -x "[id]:<1490>d [-1]" -y[temperature] -y[humidity] -l
"temperature": 25.1
"humidity": 40.0
bash $ 

-lयदि आप मुद्रित लेबल नहीं चाहते हैं तो ड्रॉप के ऊपर के उदाहरण में

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