Jq का उपयोग करके 2 फ़ाइलों से 2 JSON ऑब्जेक्ट्स को कैसे मर्ज करें?


124

मैं शेल स्क्रिप्ट में jq टूल्स (jq-json-processor) का उपयोग ज्यूस को पार्स करने के लिए कर रहा हूं ।

मुझे 2 json फाइलें मिली हैं और उन्हें एक अनोखी फाइल में मर्ज करना चाहते हैं

यहाँ फ़ाइलों की सामग्री:

file1

{
    "value1": 200,
    "timestamp": 1382461861,
    "value": {
        "aaa": {
            "value1": "v1",
            "value2": "v2"
        },
        "bbb": {
            "value1": "v1",
            "value2": "v2"
        },
        "ccc": {
            "value1": "v1",
            "value2": "v2"
        }
    }
}

करें 2

{
    "status": 200,
    "timestamp": 1382461861,
    "value": {
        "aaa": {
            "value3": "v3",
            "value4": 4
        },
        "bbb": {
            "value3": "v3"
        },      
        "ddd": {
            "value3": "v3",
            "value4": 4
        }
    }
}

अपेक्षित परिणाम

{
    "value": {
        "aaa": {
            "value1": "v1",
            "value2": "v2",
            "value3": "v3",
            "value4": 4
        },
        "bbb": {
            "value1": "v1",
            "value2": "v2",
            "value3": "v3"
        },
        "ccc": {
            "value1": "v1",
            "value2": "v2"
        },
        "ddd": {
            "value3": "v3",
            "value4": 4
        }
    }
}

मैं बहुत सारे कॉम्बिनेशन की कोशिश करता हूं, लेकिन मुझे जो एकमात्र परिणाम मिलता है वह निम्नलिखित है, जो अपेक्षित परिणाम नहीं है:

{
  "ccc": {
    "value2": "v2",
    "value1": "v1"
  },
  "bbb": {
    "value2": "v2",
    "value1": "v1"
  },
  "aaa": {
    "value2": "v2",
    "value1": "v1"
  }
}
{
  "ddd": {
    "value4": 4,
    "value3": "v3"
  },
  "bbb": {
    "value3": "v3"
  },
  "aaa": {
    "value4": 4,
    "value3": "v3"
  }
}

इस कमांड का उपयोग करना:

jq -s '.[].value' file1 file2

1
क्या आपने jsontool की कोशिश की है? github.com/trentm/json
नैनो तबोदा

अभी नहीं, मैं देख लूंगा। Thx
जेन्फी

jsonउपयोग के साथ ऐसा करने के लिए:cat f1 f2 | json --deep-merge
xer0x

जहाँ / आपको json@ xer0x कैसे मिलता है ?
गस

@Gus ओह, jsonटूल पाने के लिए github.com/trentm/json पर जाएं
xer0x

जवाबों:


155

1.4 के बाद से यह अब *ऑपरेटर के साथ संभव है । जब दो ऑब्जेक्ट दिए जाते हैं, तो यह उन्हें पुनरावर्ती रूप से मर्ज कर देगा। उदाहरण के लिए,

jq -s '.[0] * .[1]' file1 file2

महत्वपूर्ण: -s (--slurp)ध्वज को नोट करें , जो एक ही सरणी में फ़ाइलें डालता है।

आपको मिलेगा:

{
  "value1": 200,
  "timestamp": 1382461861,
  "value": {
    "aaa": {
      "value1": "v1",
      "value2": "v2",
      "value3": "v3",
      "value4": 4
    },
    "bbb": {
      "value1": "v1",
      "value2": "v2",
      "value3": "v3"
    },
    "ccc": {
      "value1": "v1",
      "value2": "v2"
    },
    "ddd": {
      "value3": "v3",
      "value4": 4
    }
  },
  "status": 200
}

यदि आप अन्य कुंजी से छुटकारा पाना चाहते हैं (जैसे आपका अपेक्षित परिणाम), तो ऐसा करने का एक तरीका यह है:

jq -s '.[0] * .[1] | {value: .value}' file1 file2

या संभवत: कुछ हद तक अधिक कुशल (क्योंकि यह किसी भी अन्य मूल्यों को विलय नहीं करता है):

jq -s '.[0].value * .[1].value | {value: .}' file1 file2

2
ध्यान दें : -sध्वज महत्वपूर्ण है क्योंकि इसके बिना दो ऑब्जेक्ट एक सरणी में नहीं हैं।
जॉन मोरेल्स

1
@SimoKinnunen यहाँ हम दो json फ़ाइलों का विलय कर रहे हैं। क्या 1 जसन चर और अन्य जसन फ़ाइल का होना संभव है। मैंने कोशिश की लेकिन यह मेरे लिए काम नहीं कर रहा है!
जयेश ढांडा

यदि व्यक्तिगत फ़ाइलों को एक कुंजी द्वारा सॉर्ट किया जाता है, तो क्या परिणामस्वरूप फ़ाइल में ऑर्डर को संरक्षित करना संभव है?
सिंह

@SimoKinnunen मैं इस कमांड का उपयोग कर रहा हूं: "jq -s 'add' config.json other / *। Json" लेकिन जब मैं एक "cat config.json" करता हूं तो इसका विलय नहीं होता है। मैं आउटपुट को वापस फाइल में कैसे डाल सकता हूं?
रेनैटो बियाबानो

63

उपयोग करें jq -s add:

$ echo '{"a":"foo","b":"bar"} {"c":"baz","a":0}' | jq -s add
{
  "a": 0,
  "b": "bar",
  "c": "baz"
}

यह स्टन से सभी JSON टेक्स्ट को एक अरै ( jq -sऐसा करता है) में पढ़ता है तब यह उन्हें "कम" कर देता है।

( addइस रूप में परिभाषित किया गया है def add: reduce .[] as $x (null; . + $x);, जो इनपुट सरणी के / ऑब्जेक्ट के मानों पर निर्भर करता है और उन्हें जोड़ता है। ऑब्जेक्ट जोड़ == मर्ज करें।)


4
क्या इस दृष्टिकोण के साथ पुनरावर्ती मर्ज (* ऑपरेटर) करना संभव है?
डेव फोस्टर

1
@DaveFoster हाँ, कुछ इस तरह से reduce .[] as $x ({}; . * $x)- जरीब का जवाब भी देखें ।
चरखी १६'१

इसने मुझे Ansible और jq का उपयोग करके दो json फ़ाइलों को मर्ज करने में मदद की। धन्यवाद।
फेलिप अल्वारेज़

35

कौन जानता है कि आपको अभी भी इसकी आवश्यकता है, लेकिन यहां समाधान है।

एक बार जब आप --slurpविकल्प पर पहुंच जाते हैं , तो यह आसान है!

--slurp/-s:
    Instead of running the filter for each JSON object in the input,
    read the entire input stream into a large array and run the filter just once.

फिर +ऑपरेटर वही करेगा जो आप चाहते हैं:

jq -s '.[0] + .[1]' config.json config-user.json

(ध्यान दें: यदि आप दाईं फाइल वालों के साथ बाईं फाइल को ओवरराइट करने के बजाय आंतरिक वस्तुओं को मर्ज करना चाहते हैं, तो आपको मैन्युअल रूप से करने की आवश्यकता होगी)


19

यहाँ एक संस्करण है जो *वस्तुओं की एक मनमानी संख्या पर पुनरावर्ती (उपयोग ) करता है :

echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' | jq --slurp 'reduce .[] as $item ({}; . * $item)'
{
  "A": {
    "a": 1,
    "b": 2
  },
  "B": 3
}

2
बहुत बढ़िया जवाब। अच्छी तरह से काम करता है जब एक निर्देशिका में सभी फ़ाइलों को विलय:jq -s 'reduce .[] as $item ({}; . * $item)' *.json
जॉन एलमोर

7

सबसे पहले, {"value": .value} को केवल {value} के लिए संक्षिप्त किया जा सकता है।

दूसरा, --argfile विकल्प (jq 1.4 और jq 1.5 में उपलब्ध) ब्याज का हो सकता है क्योंकि यह --slurp विकल्प का उपयोग करने से बचता है।

इन्हें एक साथ रखकर, दो फाइलों में दो वस्तुओं को निर्दिष्ट तरीके से इस प्रकार जोड़ा जा सकता है:

$ jq -n --argfile o1 file1 --argfile o2 file2 '$o1 * $o2 | {value}'

'-N' झंडा स्टैक से नहीं पढ़ने के लिए jq को बताता है, क्योंकि इनपुट यहाँ --argfile विकल्पों से आ रहे हैं।


2
--argile--slurpfile
jq के

3

इसका उपयोग कमांड पर निर्दिष्ट किसी भी फाइल को मर्ज करने के लिए किया जा सकता है:

jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json

या फ़ाइलों की संख्या के लिए यह

jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json

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