Bash 关联数组按值排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8217049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash associative array sorting by value
提问by Graf
I get the following output:
我得到以下输出:
Pushkin - 100500
Gogol - 23
Dostoyevsky - 9999
Which is the result of the following script:
这是以下脚本的结果:
for k in "${!authors[@]}"
do
echo $k ' - ' ${authors["$k"]}
done
All I want is to get the output like this:
我想要的只是得到这样的输出:
Pushkin - 100500
Dostoyevsky - 9999
Gogol - 23
which means that the keys in associative array should be sorted by value. Is there an easy method to do so?
这意味着关联数组中的键应该按值排序。有没有一种简单的方法可以做到这一点?
回答by Andrew Schulman
You can easily sort your output, in descending numerical order of the 3rd field:
您可以轻松地按第三个字段的数字降序对输出进行排序:
for k in "${!authors[@]}"
do
echo $k ' - ' ${authors["$k"]}
done |
sort -rn -k3
See sort(1) for more about the sort
command. This just sorts output lines; I don't know of any way to sort an array directly in bash.
有关该sort
命令的更多信息,请参阅 sort(1) 。这只是对输出行进行排序;我不知道有什么方法可以直接在 bash 中对数组进行排序。
I also can't see how the above can give you names ("Pushkin" et al.) as array keys. In bash, array keys are always integers.
我也看不到上面的内容如何为您提供名称(“Pushkin”等)作为数组键。在 bash 中,数组键总是整数。
回答by Werner Lehmann
Alternatively you can sort the indexes and use the sorted list of indexes to loop through the array:
或者,您可以对索引进行排序并使用已排序的索引列表来遍历数组:
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
回答by WaffleSouffle
Extending the answer from @AndrewSchulman, using -rn as a global sort option reverses all columns. In this example, authors with the same associative array value will be output by reverse order of name.
扩展@AndrewSchulman 的答案,使用 -rn 作为全局排序选项会反转所有列。在这个例子中,具有相同关联数组值的作者将按姓名的相反顺序输出。
For example
例如
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
will output
会输出
Pushkin - 10050 Dostoyevsky - 9999 Tolstoy - 23 Gogol - 23可以在列说明符之后提供用于对特定列进行排序的选项。IE
sort -k3rn
sort -k3rn
Note that keys can be specified as spans. Here -k3
happens to be fine because it is the final span, but to use only column 3 explicitly (in case further columns were added), it should be specified as -k3,3
,
Similarly to sort by column three in descending order, and then column one in ascending order (which is probably what is desired in this example):
请注意,键可以指定为跨度。这里-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
will output
会输出
Pushkin - 10050 Dostoyevsky - 9999 Gogol - 23 Tolstoy - 23
回答by mz4wheeler
The best way to sort a bash associative array by VALUE is to NOT sort it.
按 VALUE 对 bash 关联数组进行排序的最佳方法是不对它进行排序。
Instead, get the list of VALUE:::KEYS, sort that list into a new KEY LIST, and iterate through the list.
相反,获取 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 }'
)
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]