2011-11-21 99 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命令见排序。这只是排序输出线;我不知道有什么方法直接在bash中对数组进行排序。

我也看不出上面可以给你的名字(“普希金”等)作为数组键。在bash中,数组键总是整数。

+6

击4.0增加关联数组,其中键可以是字符串。 –

+2

好吧,我会......你说得对。它只需要'declare -A authors'。 –

+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

Boo,嘘声:'echo -e'。考虑'printf的“%s的\ n”“$ {authors_indexes [@]}”'扩展的阵列成多行的方式,不依赖于违反POSIX SH(不只是扩展的,但实际行为:任何参数除了'-n'需要打印它的文本,除非它包含反斜杠或'-n'存在,在这种情况下,行为完全是实现定义的)。或'printf的“%s的\ 0”“$ {数组[@]}”'展开数组作为NUL-分隔字符串,因此,即使你有你的钥匙文字换行(其中*是*法律,工程的方式)。 –

+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 
选项可以在列说明后提供。 即 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