我得到以下输出:
Pushkin - 100500
Gogol - 23
Dostoyevsky - 9999
以下脚本的结果如下:
for k in "${!authors[@]}"
do
echo $k ' - ' ${authors["$k"]}
done
我想要的就是得到这样的输出:
Pushkin - 100500
Dostoyevsky - 9999
Gogol - 23
表示关联数组中的键应按值排序。有一种简单的方法吗?
答案 0 :(得分:22)
您可以按第3个字段的降序数字轻松对输出进行排序:
for k in "${!authors[@]}"
do
echo $k ' - ' ${authors["$k"]}
done |
sort -rn -k3
有关sort
命令的更多信息,请参阅sort(1)。这只是排序输出线;我不知道有什么方法可以直接在bash中对数组进行排序。
我也看不出上面的内容如何将你的名字(“Pushkin”等)作为数组键。在bash中,数组键总是整数。
答案 1 :(得分: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
答案 2 :(得分: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可以在列说明符之后提供用于对特定列进行排序的选项。 即
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
答案 3 :(得分:1)
按VALUE排序bash关联数组的最好方法是不对其进行排序。
相反,获取VALUE ::: KEYS的列表,将该列表排序为新的KEY LIST,然后遍历该列表。
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]
答案 4 :(得分:0)
如果您可以假设该值始终是一个数字(没有空格),但希望允许键中有空格的可能性:
for k in "${!authors[@]}"; do
echo "${authors["$k"]} ${k}"
done | sort -rn | while read number author; do
echo "${author} - ${number}"
done
示例:
$ declare -A authors
$ authors=(['Shakespeare']=1 ['Kant']=2 ['Von Neumann']=3 ['Von Auersperg']=4)
$ for k in "${!authors[@]}"; do echo "${authors["$k"]} ${k}"; done | sort -rn | while read number author; do echo "${author} - ${number}"; done
Von Auersperg - 4
Von Neumann - 3
Kant - 2
Shakespeare - 1
$
如果键中没有空格,则所选答案似乎有效,但如果有则失败:
$ declare -A authors
$ authors=(['Shakespeare']=1 ['Kant']=2 ['Von Neumann']=3 ['Von Auersperg']=4)
$ for k in "${!authors[@]}"; do echo $k ' - ' ${authors["$k"]}; done | sort -rn -k 3
Kant - 2
Shakespeare - 1
Von Neumann - 3
Von Auersperg - 4
$