मुझे लगता है कि आप वहां दो अलग चीजें पूछ रहे हैं।
क्या लूप के बिना इस जानकारी को प्रिंट करने का एक तरीका है?
हां, लेकिन वे केवल लूप का उपयोग करने के रूप में अच्छे नहीं हैं।
क्या आउटपुट का केवल कुंजी = मान भाग प्राप्त करने / प्रिंट करने के लिए कोई क्लीनर तरीका है?
हाँ, for
पाश। इसके फायदे हैं कि इसके लिए बाहरी कार्यक्रमों की आवश्यकता नहीं है, यह सीधा है, और यह आश्चर्य के बिना सटीक आउटपुट प्रारूप को नियंत्रित करना आसान बनाता है।
कोई भी समाधान जो declare -p
( typeset -p
) के आउटपुट को संभालने की कोशिश करता है ( क) को स्वयं को वैरिएबल की संभावना जो कि कोष्ठक या कोष्ठक से युक्त है, बी) वह उद्धरण जो declare -p
इसे शेल के लिए आउटपुट मान्य इनपुट बनाने के लिए जोड़ना है।
उदाहरण के लिए, आपका विस्तार b="${a##*(}"
कुछ मूल्यों को खाता है, यदि किसी भी कुंजी / मूल्य में एक प्रारंभिक कोष्ठक है। ऐसा इसलिए है क्योंकि आपने उपयोग किया है ##
, जो सबसे लंबे समय तक उपसर्ग को हटा देता है । उसी के लिए c="${b%% )*}"
। यद्यपि आप निश्चित रूप से declare
अधिक सटीक रूप से मुद्रित बॉयलरप्लेट से मेल खा सकते हैं, फिर भी आपके पास एक कठिन समय होगा यदि आप नहीं चाहते कि यह सब उद्धृत किया जाए।
यह बहुत अच्छा नहीं लगता है जब तक कि आपको इसकी आवश्यकता न हो।
$ declare -A array=([abc]="'foobar'" [def]='"foo bar"')
$ declare -p array
declare -A array='([def]="\"foo bar\"" [abc]="'\''foobar'\''" )'
for
लूप के साथ , जैसा कि आप चाहते हैं आउटपुट स्वरूप चुनना आसान है:
# without quoting
$ for x in "${!array[@]}"; do printf "[%s]=%s\n" "$x" "${array[$x]}" ; done
[def]="foo bar"
[abc]='foobar'
# with quoting
$ for x in "${!array[@]}"; do printf "[%q]=%q\n" "$x" "${array[$x]}" ; done
[def]=\"foo\ bar\"
[abc]=\'foobar\'
वहाँ से, आउटपुट फॉर्मेट को बदलना आसान है अन्यथा (कोष्ठक के चारों ओर के कोष्ठक हटा दें, सभी कुंजी / मान युग्मों को एक पंक्ति में रखें)। यदि आपको शेल के अलावा किसी अन्य चीज़ के लिए उद्धृत करने की आवश्यकता है, तो आपको अभी भी इसे स्वयं करने की आवश्यकता होगी, लेकिन कम से कम आपके पास काम करने के लिए कच्चा डेटा होगा। (यदि आपके पास कुंजियों या मूल्यों में नई रूपरेखाएँ हैं, तो आपको संभवतः कुछ उद्धरण की आवश्यकता होगी।)
वर्तमान बैश (4.4, मुझे लगता है) के साथ, आप printf "[%s]=%s" "${x@Q}" "${array[$x]@Q}"
इसके बजाय भी उपयोग कर सकते हैं printf "%q=%q"
। यह कुछ हद तक एक अच्छे उद्धरण स्वरूप का उत्पादन करता है, लेकिन निश्चित रूप से लिखने के लिए याद रखने के लिए थोड़ा अधिक काम है। (और यह @
सरणी कुंजी के कोने मामले को %q
उद्धृत करता है , जो उद्धरण नहीं करता है।)
अगर लिखने के लिए लूप बहुत थका हुआ लगता है, तो इसे कहीं फंक्शन में सेव करें (यहाँ उद्धृत किए बिना):
printarr() { declare -n __p="$1"; for k in "${!__p[@]}"; do printf "%s=%s\n" "$k" "${__p[$k]}" ; done ; }
और फिर बस उस का उपयोग करें:
$ declare -A a=([a]=123 [b]="foo bar" [c]="(blah)")
$ printarr a
a=123
b=foo bar
c=(blah)
अनुक्रमित सरणियों के साथ भी काम करता है:
$ b=(abba acdc)
$ printarr b
0=abba
1=acdc
printf ...%q...
वेरिएंट का आउटपुट शेल के लिए प्रबलित करने के लिए उपयुक्त नहीं है यदि सरणी में एक@
कुंजी है क्योंकि% q इसे उद्धृत नहीं करता है और इसमेंa=([@]=value)
एक सिंटैक्स त्रुटि हैbash
।