Search code examples
shellunixsortingcommand-lineawk

UNIX shell: sort a string by word length and by ASCII order ignoring case


I would like to sort a string by length and then by ASCII order(upper and lower case are equal) with a unix command.

string = [a-z][A-Z][0-9]

For example:

"A a b B cc ca cd" : 
=> A a b B
=> ca cc cd

"Hello stackoverflow how are you today"
=> are how you
=> Hello today
=> stackoverflow

Solution

  • I wrote an ugly (maybe) awk|sort|awk line to do the job. it could be done in one awk process too, however, I am a bit lazy, just go to the dirty and quick way.

    echo yourStr|awk '{
    split($0,o); for(x in o) print length(o[x]),o[x]}'|sort -n|awk '!p{printf $2;p=$1;next}$1==p{printf " "$2}$1!=p{printf "\n"$2;p=$1}' 
    

    let's take an example:

    "Hello stackoverflow how are you today foo bar xoo yoo ooo"
    

    try with above line:

    kent$  echo "Hello stackoverflow how are you today foo bar xoo yoo ooo"|awk '{
    split($0,o); for(x in o) print length(o[x]),o[x]}'|sort -n|awk '!p{printf $2;p=$1;next}$1==p{printf " "$2}$1!=p{printf "\n"$2;p=$1}'
    are bar foo how ooo xoo yoo you
    Hello today
    stackoverflow     
    

    test with your first example:

    kent$  echo "A a b B cc ca cd" |awk '{
    pipe quote> split($0,o); for(x in o) print length(o[x]),o[x]}'|sort -n|awk '!p{printf $2;p=$1;next}$1==p{printf " "$2}$1!=p{printf "\n"$2;p=$1}' 
    a A b B
    ca cc cd