Skip to main content
Simplified.
Source Link
user232326
user232326

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlines and sparse arrays):

#!/bin/bash
a=in=(
    "tiny string"
    "the longest
        string inalso thecontaining
 list"       newlines"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
    "test * string"
    "*"
    "?"
    "[abc]"
)

readarray -td $'\0' sorted < <(
                    for i in "${!array[@]in[@]}"
                    do     printf '%s\0''%s %s\0' "${array[i]/#/${#array[i]#i}" }";"$i";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <( for i in "${!array[@]in[@]}"; do";do printf '%s\0''%s %s\0' "${array[i]/#/${#array[i]#i}" }";"$i"; done | sort -bz -k1rnk1,1rn -k2 | cut -zd " " -f2- )

On execution

$ ./script
the longest
        string inalso thecontaining
 list       newlines
also a medium string
medium string
middle string
test * string
short string
tiny string
[abc]
?
*

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlines and sparse arrays):

#!/bin/bash
a=(
    "tiny string"
    "the longest string in the list"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
)

readarray -td $'\0' sorted < <(
                    for i in "${!array[@]}"
                    do     printf '%s\0' "${array[i]/#/${#array[i]} }";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <( for i in "${!array[@]}"; do printf '%s\0' "${array[i]/#/${#array[i]} }"; done | sort -bz -k1rn -k2 | cut -zd " " -f2- )

On execution

$ ./script
the longest string in the list
also a medium string
medium string
middle string
short string
tiny string

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlines and sparse arrays):

#!/bin/bash
in=(
    "tiny string"
    "the longest
        string also containing
        newlines"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
    "test * string"
    "*"
    "?"
    "[abc]"
)

readarray -td $'\0' sorted < <(
                    for i in "${in[@]}"
                    do     printf '%s %s\0' "${#i}" "$i";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <(for i in "${in[@]}";do printf '%s %s\0' "${#i}" "$i"; done | sort -bz -k1,1rn -k2 | cut -zd " " -f2-)

On execution

$ ./script
the longest
        string also containing
        newlines
also a medium string
medium string
middle string
test * string
short string
tiny string
[abc]
?
*
added 4 characters in body
Source Link
user232326
user232326

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlinessafe for newlines and sparse arrays):

#!/bin/bash
a=(
    "tiny string"
    "the longest string in the list"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
)

readarray -td $'\0' sorted < <(
                    for i in "${!array[@]}"
                    do     printf '%s\0' "${array[i]/#/${#array[i]} }";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <( for i in "${!array[@]}"; do printf '%s\0' "${array[i]/#/${#array[i]} }"; done | sort -bz -k1rn -k2 | cut -zd " " -f2- )

On execution

$ ./script
the longest string in the list
also a medium string
medium string
middle string
short string
tiny string

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlines and sparse arrays):

#!/bin/bash
a=(
    "tiny string"
    "the longest string in the list"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
)

readarray -td $'\0' sorted < <(
                    for i in "${!array[@]}"
                    do     printf '%s\0' "${array[i]/#/${#array[i]} }";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <( for i in "${!array[@]}"; do printf '%s\0' "${array[i]/#/${#array[i]} }"; done | sort -bz -k1rn -k2 | cut -zd " " -f2- )

On execution

$ ./script
the longest string in the list
also a medium string
medium string
middle string
short string
tiny string

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlines and sparse arrays):

#!/bin/bash
a=(
    "tiny string"
    "the longest string in the list"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
)

readarray -td $'\0' sorted < <(
                    for i in "${!array[@]}"
                    do     printf '%s\0' "${array[i]/#/${#array[i]} }";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <( for i in "${!array[@]}"; do printf '%s\0' "${array[i]/#/${#array[i]} }"; done | sort -bz -k1rn -k2 | cut -zd " " -f2- )

On execution

$ ./script
the longest string in the list
also a medium string
medium string
middle string
short string
tiny string
Source Link
user232326
user232326

A hackish? (complex) and fast one line way to sort the array by length
(safe for newlines and sparse arrays):

#!/bin/bash
a=(
    "tiny string"
    "the longest string in the list"
    "middle string"
    "medium string"
    "also a medium string"
    "short string"
)

readarray -td $'\0' sorted < <(
                    for i in "${!array[@]}"
                    do     printf '%s\0' "${array[i]/#/${#array[i]} }";
                    done |
                            sort -bz -k1,1rn -k2 |
                            cut -zd " " -f2-
                    )

printf '%s\n' "${sorted[@]}"

On one line:

readarray -td $'\0' sorted < <( for i in "${!array[@]}"; do printf '%s\0' "${array[i]/#/${#array[i]} }"; done | sort -bz -k1rn -k2 | cut -zd " " -f2- )

On execution

$ ./script
the longest string in the list
also a medium string
medium string
middle string
short string
tiny string