2011-11-21 24 views
16

मैं निम्नलिखित उत्पादन:बैश साहचर्य सरणी छँटाई

Pushkin - 100500 
Gogol - 23 
Dostoyevsky - 9999 

कौन सा निम्न स्क्रिप्ट का परिणाम है:

:

for k in "${!authors[@]}" 
do 
    echo $k ' - ' ${authors["$k"]} 
done 

सभी मैं चाहता हूँ इस तरह उत्पादन प्राप्त करने के लिए है

Pushkin - 100500 
Dostoyevsky - 9999 
Gogol - 23 

जिसका अर्थ है कि सहयोगी सरणी में कुंजी को मूल्य द्वारा क्रमबद्ध किया जाना चाहिए। क्या ऐसा करने के लिए कोई आसान तरीका है?

उत्तर

17

आप आसानी से अपनी उत्पादन सॉर्ट कर सकते हैं 3 क्षेत्र के संख्यात्मक अवरोही क्रम में:

for k in "${!authors[@]}" 
do 
    echo $k ' - ' ${authors["$k"]} 
done | 
sort -rn -k3 

(1) sort आदेश के बारे में अधिक के लिए तरह देखें। यह सिर्फ आउटपुट लाइनों की तरह है; मैं सीधे सरणी में सरणी को सॉर्ट करने के किसी भी तरीके से नहीं जानता।

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

+6

बैश 4.0 साहचर्य सरणियों जहां कुंजी तार हो सकता है कहते हैं। –

+2

ठीक है मैं ... आप सही हो। इसे सिर्फ 'घोषणाएं' लेखक की आवश्यकता है। –

+1

आपका समाधान काम करता है। जहां तक ​​मैं समझता हूं, यह सिर्फ आउटपुट स्ट्रिंग्स को टाइप करता है, न कि एसोसिएटिव सरणी की सामग्री, लेकिन वैसे भी, आउटपुट का उत्पादन मुझे चाहिए। – Graf

7

वैकल्पिक रूप से आप अनुक्रमणिका सॉर्ट और सरणी लूप करने के लिए इंडेक्सों का हल कर सूची का उपयोग कर सकते हैं:

authors_indexes=(${!authors[@]}) 
IFS=$'\n' authors_sorted=($(echo -e "${authors_indexes[@]/%/\n}" | sed -r -e 's/^ *//' -e '/^$/d' | sort)) 

for k in "${authors_sorted[@]}"; do 
    echo $k ' - ' ${authors["$k"]} 
done 
+0

बू, उसका फिर से: 'echo -e'। 'Printf'% s \ n '"$ {authors_indexes [@]}" पर क्लिक करें ताकि एक सरणी को कई पंक्तियों में विस्तारित किया जा सके जो POSIX sh के उल्लंघनों पर निर्भर नहीं है (केवल एक्सटेंशन नहीं, बल्कि वास्तविक उल्लंघन: कोई भी तर्क '-n' के अलावा इसके पाठ को मुद्रित करने की आवश्यकता है, जब तक कि इसमें बैकस्लाश या '-n' मौजूद न हो, जिसमें केस व्यवहार पूरी तरह कार्यान्वयन-परिभाषित होता है)। या 'printf '% s \ 0'" $ {array [@]} "'सरणी को एनयूएल-डिलीमिट स्ट्रिंग्स के रूप में विस्तारित करने के लिए, इस प्रकार इस तरह से काम करता है कि आपके कुंजी में शाब्दिक न्यूलाइन है (जो * कानूनी हैं)। –

+0

... http://pubs.opengroup.org/onlinepubs/009695399/utilities/echo.html, विशेष रूप से आवेदन उपयोग अनुभाग देखें। –

2

@AndrewSchulman से जवाब का विस्तार, -rn एक वैश्विक प्रकार विकल्प के रूप में उपयोग करते हुए सभी स्तंभों को उलट देता है। इस उदाहरण में, एक ही सहयोगी सरणी मान वाले लेखक नाम के विपरीत क्रम से आउटपुट होंगे।

उदाहरण

declare -A authors 
authors=([Pushkin]=10050 [Gogol]=23 [Dostoyevsky]=9999 [Tolstoy]=23) 

for k in "${!authors[@]}" 
do 
    echo $k ' - ' ${authors["$k"]} 
done | sort -rn -k3 

इच्छा उत्पादन

 
Pushkin - 10050 
Dostoyevsky - 9999 
Tolstoy - 23 
Gogol - 23 
विशिष्ट स्तंभ छँटाई करने के लिए विकल्प के लिए स्तंभ विनिर्देशक के बाद प्रदान किया जा सकता। i.e. sort -k3rn

ध्यान दें कि कुंजी को स्पैन के रूप में निर्दिष्ट किया जा सकता है। यहां -k3 ठीक होने वाला है क्योंकि यह अंतिम अवधि है, लेकिन केवल कॉलम 3 का उपयोग करने के लिए स्पष्ट रूप से (यदि आगे कॉलम जोड़े गए हैं), इसे -k3,3, के रूप में निर्दिष्ट किया जाना चाहिए, इसी तरह कॉलम तीन को अवरोही क्रम में क्रमबद्ध करने के लिए, और फिर कॉलम आरोही क्रम में एक (जो शायद है क्या इस उदाहरण में वांछित है):

declare -A authors 
authors=([Pushkin]=10050 [Gogol]=23 [Dostoyevsky]=9999 [Tolstoy]=23) 
for k in "${!authors[@]}" 
do 
    echo $k ' - ' ${authors["$k"]} 
done | sort -k3,3rn -k1,1 

इच्छा उत्पादन

 
Pushkin - 10050 
Dostoyevsky - 9999 
Gogol - 23 
Tolstoy - 23 

संबंधित मुद्दे