Skip to main content
2 of 5
added 48 characters in body
Kusalananda
  • 355.9k
  • 42
  • 735
  • 1.1k
readarray -t array < <(
for str in "${array[@]}"; do
    printf '%d\t%s\n' "${#str}" "$str"
done | sort -k 1,1nr -k 2 | cut -f2- )

This reads the values of the sorted array from a process substitution.

Tho process substitution contains a loop. The loop output each element of the array prepended by the element's length and a tab character in-between.

The output of the loop is sorted numerically from largest to smallest (and alphabetically if the lengths are the same, use -k 2r in place of -k 2 to reverse the alphabetical order) and the result of that is sent to cut which deletes the column with the string lengths.

Sort test script followed by a test run:

array=(
    "tiny string"
    "the longest string in the list"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
)

readarray -t array < <(
for str in "${array[@]}"; do
    printf '%d\t%s\n' "${#str}" "$str"
done | sort -k 1,1nr -k2 | cut -f2- )

printf '%s\n' "${array[@]}"
$ bash script.sh
the longest string in the list
also a medium string
medium string
middle string
short string
tiny string
Kusalananda
  • 355.9k
  • 42
  • 735
  • 1.1k