Bash tableau associatif tri par valeur
j'obtiens le résultat suivant:
Pushkin - 100500
Gogol - 23
Dostoyevsky - 9999
Qui est le résultat du script suivant:
for k in "${!authors[@]}"
do
echo $k ' - ' ${authors["$k"]}
done
Tout ce que je veux est d'obtenir à la sortie comme ceci:
Pushkin - 100500
Dostoyevsky - 9999
Gogol - 23
ce qui signifie que les clés dans le tableau associatif doivent être triées par valeur. Est-il une méthode simple pour le faire?
3 réponses
Vous pouvez facilement trier votre sortie, dans l'ordre numérique décroissant de la 3ème champ:
for k in "${!authors[@]}"
do
echo $k ' - ' ${authors["$k"]}
done |
sort -rn -k3
voir sort (1) pour plus d'informations sur le sort
la commande. Cela permet juste de trier les lignes de sortie; Je ne sais pas comment trier un tableau directement dans bash.
Je ne vois pas non plus comment ce qui précède peut vous donner des noms ("Pushkin" et al.) comme la matrice de touches. Dans bash, les clés de tableau sont toujours des entiers.
Vous pouvez aussi trier les index et utiliser la liste des index triés pour faire une boucle à travers le tableau:
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
étendre la réponse de @AndrewSchulman, en utilisant -rn comme option de tri global inverse toutes les colonnes. Dans cet exemple, les auteurs avec la même valeur de tableau associatif seront produits par ordre inverse de nom.
Par exemple
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
sortie
Pushkin - 10050 Dostoyevsky - 9999 Tolstoy - 23 Gogol - 23Options pour le tri des colonnes spécifiques peuvent être fournies après le spécificateur de colonne. i.e.
sort -k3rn
notez que les clés peuvent être spécifiées comme des portées. Ici -k3
arrive à être bien parce que c'est la portée finale, mais pour utiliser seulement la colonne 3 explicitement (dans le cas où d'autres colonnes ont été ajoutées), il doit être spécifié comme -k3,3
,
De même pour trier par colonne trois dans l'ordre décroissant, puis une colonne dans l'ordre croissant (ce qui est probablement ce qui est souhaité dans cet exemple):
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
sortie
Pushkin - 10050 Dostoyevsky - 9999 Gogol - 23 Tolstoy - 23