Bash 对 Map 的值进行降序排序
Bash sorting the values of Map in descending order
我在 bash 中声明了一个地图,如下所示
declare -A myMap
myMap=( [A:B:C:D]=813.0 [P:Q:R:S]=2346957.02 [W:X:Y:Z]=53831.93 [E:F:G:H]=113770.0)
我想在具有分隔符 (:) 的 Key 中拆分字符串,并按值的降序顺序获取输出,如下所示
P - Q - R - S - 2346957.02
E - F - G - H - 113770.0
W - X - Y - Z - 53831.93
A - B - C - D - 813.0
我正在尝试的代码如下
for k in "${!myMap[@]}"
do
arrIN=(${k//:/ })
echo ${arrIN[0]} ' - ' ${arrIN[1]} ' - ' ${arrIN[2]} ' - ' ${arrIN[3]} ' - ' ${myMap["$k"]}
done | sort ${myMap["$k"]}
但是使用我的代码的输出是这样的
E - F - G - H - 113770.0
W - X - Y - Z - 53831.93
P - Q - R - S - 2346957.02
A - B - C - D - 813.0
有没有简单的方法可以做到这一点?
如果打印原始键和值,则按第二列排序 (k2
),n
umeric r
everse.
#! /bin/bash
declare -A myMap
myMap=( [A:B:C:D]=813.0 [P:Q:R:S]=2346957.02 [W:X:Y:Z]=53831.93 [E:F:G:H]=113770.0)
for k in ${!myMap[@]} ; do
echo $k ${myMap[$k]}
done | sort -rnk2 | sed 's/[: ]/ - /g'
如果拆分key,需要按第九列排序:
for k in "${!myMap[@]}" ; do
arrIN=(${k//:/ })
echo ${arrIN[0]} - ${arrIN[1]} - ${arrIN[2]} - ${arrIN[3]} - ${myMap[$k]}
done | sort -nrk9
使用文件名通配符对键进行排序的替代方法。
#!/usr/bin/env bash
declare -A myMap
myMap=( [A:B:C:D]=813.0 [P:Q:R:S]=2346957.02 [W:X:Y:Z]=53831.93 [E:F:G:H]=113770.0)
tmpDir=
trap 'rm -fr "$tmpDir"' EXIT INT
tmpDir=$(mktemp -d)
myKeys=("${!myMap[@]}")
# Create a file per key in the temp directory
touch "${myKeys[@]/#/$tmpDir/}"
# Load keys from temp directory benefiting from auto sorting
myKeys=("$tmpDir/"*)
# Strip file path from keys
myKeys=("${myKeys[@]##*/}")
# Iterate keys in reverse order
for (( i=${#myKeys[@]}-1; i>=0; i-- )); do
k=${myKeys[i]}
# Split key by :
IFS=: read -ra ka <<<"$k"
# Get corresponding value
v=${myMap[$k]}
# Print joined key elements with " - " followed by value
printf '%s%s%s%s%s\n' "${ka[@]/%/ - }" "$v"
done
我在 bash 中声明了一个地图,如下所示
declare -A myMap
myMap=( [A:B:C:D]=813.0 [P:Q:R:S]=2346957.02 [W:X:Y:Z]=53831.93 [E:F:G:H]=113770.0)
我想在具有分隔符 (:) 的 Key 中拆分字符串,并按值的降序顺序获取输出,如下所示
P - Q - R - S - 2346957.02
E - F - G - H - 113770.0
W - X - Y - Z - 53831.93
A - B - C - D - 813.0
我正在尝试的代码如下
for k in "${!myMap[@]}"
do
arrIN=(${k//:/ })
echo ${arrIN[0]} ' - ' ${arrIN[1]} ' - ' ${arrIN[2]} ' - ' ${arrIN[3]} ' - ' ${myMap["$k"]}
done | sort ${myMap["$k"]}
但是使用我的代码的输出是这样的
E - F - G - H - 113770.0
W - X - Y - Z - 53831.93
P - Q - R - S - 2346957.02
A - B - C - D - 813.0
有没有简单的方法可以做到这一点?
如果打印原始键和值,则按第二列排序 (k2
),n
umeric r
everse.
#! /bin/bash
declare -A myMap
myMap=( [A:B:C:D]=813.0 [P:Q:R:S]=2346957.02 [W:X:Y:Z]=53831.93 [E:F:G:H]=113770.0)
for k in ${!myMap[@]} ; do
echo $k ${myMap[$k]}
done | sort -rnk2 | sed 's/[: ]/ - /g'
如果拆分key,需要按第九列排序:
for k in "${!myMap[@]}" ; do
arrIN=(${k//:/ })
echo ${arrIN[0]} - ${arrIN[1]} - ${arrIN[2]} - ${arrIN[3]} - ${myMap[$k]}
done | sort -nrk9
使用文件名通配符对键进行排序的替代方法。
#!/usr/bin/env bash
declare -A myMap
myMap=( [A:B:C:D]=813.0 [P:Q:R:S]=2346957.02 [W:X:Y:Z]=53831.93 [E:F:G:H]=113770.0)
tmpDir=
trap 'rm -fr "$tmpDir"' EXIT INT
tmpDir=$(mktemp -d)
myKeys=("${!myMap[@]}")
# Create a file per key in the temp directory
touch "${myKeys[@]/#/$tmpDir/}"
# Load keys from temp directory benefiting from auto sorting
myKeys=("$tmpDir/"*)
# Strip file path from keys
myKeys=("${myKeys[@]##*/}")
# Iterate keys in reverse order
for (( i=${#myKeys[@]}-1; i>=0; i-- )); do
k=${myKeys[i]}
# Split key by :
IFS=: read -ra ka <<<"$k"
# Get corresponding value
v=${myMap[$k]}
# Print joined key elements with " - " followed by value
printf '%s%s%s%s%s\n' "${ka[@]/%/ - }" "$v"
done