द स्कीनी
jq -r '(.[0] | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv'
या:
jq -r '(.[0] | keys_unsorted) as $keys | ([$keys] + map([.[ $keys[] ]])) [] | @csv'
विवरण
अलग
विवरणों का वर्णन करना मुश्किल है क्योंकि jq स्ट्रीम-ओरिएंटेड है, जिसका अर्थ है कि यह JSON डेटा के अनुक्रम पर संचालित होता है, बजाय एक मान के। इनपुट JSON स्ट्रीम कुछ आंतरिक प्रकार में परिवर्तित हो जाती है जिसे फ़िल्टर के माध्यम से पारित किया जाता है, फिर प्रोग्राम के अंत में आउटपुट स्ट्रीम में इनकोड किया जाता है। आंतरिक प्रकार JSON द्वारा मॉडलिंग नहीं की जाती है, और एक नामित प्रकार के रूप में मौजूद नहीं है। यह सबसे आसानी से एक नंगे सूचकांक ( .[]
) या अल्पविराम ऑपरेटर के उत्पादन की जांच करके प्रदर्शित किया जाता है (इसे सीधे डीबगर के साथ किया जा सकता है, लेकिन यह जेके के आंतरिक डेटा प्रकारों के संदर्भ में होगा, बजाय डॉसन के पीछे वैचारिक डेटा प्रकारों के) ।
$ jc -c '। []' <<< '["a", "b"]'
"ए"
"बी"
$ jc -cn '"a", "b"'
"ए"
"बी"
ध्यान दें कि आउटपुट एक सरणी नहीं है (जो होगा ["a", "b"]
)। कॉम्पैक्ट आउटपुट ( -c
विकल्प) से पता चलता है कि प्रत्येक सरणी तत्व (या ,
फ़िल्टर के लिए तर्क ) आउटपुट में एक अलग ऑब्जेक्ट बन जाता है (प्रत्येक अलग लाइन पर है)।
एक स्ट्रीम JSON-seq की तरह है , लेकिन एन्कोडेड होने पर आउटपुट विभाजक के रूप में RS के बजाय नईलाइन का उपयोग करता है । नतीजतन, इस आंतरिक प्रकार को इस उत्तर में जेनेरिक शब्द "अनुक्रम" द्वारा संदर्भित किया गया है, जिसमें एन्कोडेड इनपुट और आउटपुट के लिए "स्ट्रीम" आरक्षित है।
फ़िल्टर का निर्माण
पहले ऑब्जेक्ट की कुंजियों को इसके साथ निकाला जा सकता है:
.[0] | keys_unsorted
आम तौर पर कुंजी को उनके मूल क्रम में रखा जाएगा, लेकिन सटीक क्रम की सुरक्षा की गारंटी नहीं है। नतीजतन, उन्हें उसी क्रम में मान प्राप्त करने के लिए वस्तुओं को अनुक्रमित करने के लिए उपयोग करने की आवश्यकता होगी। यह गलत स्तंभों में मूल्यों को रोक देगा यदि कुछ वस्तुओं का एक अलग कुंजी क्रम है।
पहली पंक्ति के रूप में कुंजियों को आउटपुट करने और उन्हें अनुक्रमण के लिए उपलब्ध कराने के लिए, वे एक चर में संग्रहीत किए जाते हैं। पाइपलाइन का अगला चरण तब इस चर का संदर्भ देता है और शीर्ष लेख को आउटपुट स्ट्रीम में भेजने के लिए अल्पविराम ऑपरेटर का उपयोग करता है।
(.[0] | keys_unsorted) as $keys | $keys, ...
अल्पविराम के बाद की अभिव्यक्ति थोड़ी शामिल है। किसी ऑब्जेक्ट पर अनुक्रमणिका ऑपरेटर स्ट्रिंग्स का एक अनुक्रम ले सकता है (उदा "name", "value"
), उन स्ट्रिंग्स के लिए गुण मानों का अनुक्रम लौटाता है। $keys
एक सरणी है, अनुक्रम नहीं है, इसलिए []
इसे अनुक्रम में बदलने के लिए लागू किया जाता है,
$keys[]
जो तब पारित किया जा सकता है .[]
.[ $keys[] ]
यह भी, एक अनुक्रम का उत्पादन करता है, इसलिए इसे सरणी में बदलने के लिए सरणी कंस्ट्रक्टर का उपयोग किया जाता है।
[.[ $keys[] ]]
इस अभिव्यक्ति को एक ही वस्तु पर लागू किया जाना है। map()
बाहरी सरणी में इसे सभी वस्तुओं पर लागू करने के लिए उपयोग किया जाता है:
map([.[ $keys[] ]])
अंतिम रूप से इस चरण के लिए, इसे एक अनुक्रम में परिवर्तित किया जाता है ताकि प्रत्येक आइटम आउटपुट में एक अलग पंक्ति बन जाए।
map([.[ $keys[] ]])[]
क्यों map
केवल एक सरणी के भीतर एक अनुक्रम में बंडल इसे बाहर खोलना? map
एक सरणी पैदा करता है; .[ $keys[] ]
एक अनुक्रम पैदा करता है। map
अनुक्रम से लागू करने से .[ $keys[] ]
मूल्यों के अनुक्रम का एक सरणी उत्पन्न होगा, लेकिन चूंकि अनुक्रम एक JSON प्रकार नहीं हैं, इसलिए आपको इसके बजाय सभी मूल्यों वाले एक चपटा सरणी प्राप्त होता है।
["NSW","AU","state","New South Wales","AB","CA","province","Alberta","ABD","GB","council area","Aberdeenshire","AK","US","state","Alaska"]
प्रत्येक वस्तु से मूल्यों को अलग रखने की आवश्यकता होती है, ताकि वे अंतिम आउटपुट में अलग-अलग पंक्तियां बन जाएं।
अंत में, अनुक्रम फॉर्मेटर के माध्यम से पारित किया जाता है @csv
।
वैकल्पिक
वस्तुओं को जल्दी के बजाय, देर से अलग किया जा सकता है। एक अनुक्रम प्राप्त करने के लिए अल्पविराम ऑपरेटर का उपयोग करने के बजाय (एक अनुक्रम को सही ऑपरेंड के रूप में पारित करना), हेडर अनुक्रम ( $keys
) को एक सरणी में लपेटा जा सकता है, और +
मानों के सरणी को जोड़ने के लिए उपयोग किया जा सकता है । इसे अभी भी पारित होने से पहले एक अनुक्रम में बदलना होगा @csv
।
json2csv
है stackoverflow.com/questions/57242240/…