击关联数组由值排序

问题描述 投票:18回答:4

我得到以下的输出:

Pushkin - 100500 
Gogol - 23 
Dostoyevsky - 9999

这是下面的脚本的结果:

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

我想要的是得到的输出是这样的:

Pushkin - 100500 
Dostoyevsky - 9999
Gogol - 23

这意味着在关联数组的键应该由值进行排序。有一个简单的方法,这样做呢?

bash associative-array sorting
4个回答
22
投票

您可以轻松地整理你的输出,在降第3场的数值顺序:

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

(1)更多关于sort命令见排序。这只是排序输出线;我不知道任何方式到一个数组直接在bash排序。

我还不能看到上面怎么能给你的名字(“普希金”等)作为数组键。在bash中,数组键总是整数。


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 

3
投票

扩展从@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
Options for sorting specific columns can be provided after the column specifier. 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

2
投票

按值排序庆典关联数组最好的办法是不排序。

相反,获得价值::: KEYS,排序,列出到一个新的密钥列表的列表,并遍历列表。

declare -A ADDR
ADDR[192.168.1.3]="host3"
ADDR[192.168.1.1]="host1"
ADDR[192.168.1.2]="host2"

KEYS=$(
for KEY in ${!ADDR[@]}; do
  echo "${ADDR[$KEY]}:::$KEY"
done | sort | awk -F::: '{print $2}'
)

for KEY in $KEYS; do
  VAL=${ADDR[$KEY]}
  echo "KEY=[$KEY] VAL=[$VAL]"
done

output:
KEY=[192.168.1.1] VAL=[host1]
KEY=[192.168.1.2] VAL=[host2]
KEY=[192.168.1.3] VAL=[host3]
© www.soinside.com 2019 - 2024. All rights reserved.