I have an array with filenames as keys and a numerical value as values.

MYARRAY[00001.jpg] = 31
MYARRAY[00002.jpg] = 200
MYARRAY[00003.jpg] = 98

I need to sort them so they are ordered by value. Which I am doing with

IFS=$'\n' SORTED=($(sort <<<"${MYARRAY[*]}"))

However I lose the keys and just have numerical ones now.

Desired output would be


How can I retain the keys in such a sort?


Assuming your keys don't contain colons or newlines and your values don't contain newlines:

for key in "${!MYARRAY[@]}"; do
  printf '%s:%s\n' "$key" "${MYARRAY[$key]}"
done | sort -t : -k 2n

If you need to arrange the key in the order given by the values, read back the output:

IFS=$'\n'; set -f
    for key in "${!MYARRAY[@]}"; do
      printf '%s:%s\n' "$key" "${MYARRAY[$key]}"
    done | sort -t : -k 2n | sed 's/:.*//'))
unset IFS; set +f
|improve this answer|||||
  • I can't seem to get useful output with this so far. Could you humour me a bit. What does the sed stuff do? – dibs Mar 9 '15 at 11:51
  • @dibs The for loop prints out lines like 00001.jpg:31. The sed command removes the part after the colon. I fixed an error that caused sorted_keys to be a single string containing all the names, instead of an array as intended. – Gilles 'SO- stop being evil' Mar 9 '15 at 12:08
  • How would I modify this function to display for example only the TOP 2 file names, without the count? – pdolinaj Apr 27 '18 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.