Wednesday, October 23, 2013

Schwartzian Transform in shell



or the decorate-sort-undecorate pattern. This will sort lines of format ...-{first,second,..,ninth} in the way a human would expect.

#!/bin/bash

st() {
I=1
exec sed "
1 {
    h
    s/.*/\
first$((I+=1))\
second$((I+=1))\
third$((I+=1))\
fourth$((I+=1))\
fifth$((I+=1))\
sixth$((I+=1))\
seventh$((I+=1))\
eighth$((I+=1))\
ninth$((I+=1))\
    /
    x
    # clear it otherwise t fails for first line failed lookup
    t reset
    : reset
}
G
s/^\\(.*-\\(.*\\)\\)\\n.*\\2\\([0-9]\\{1,\\}\\).*/\1 \3/
# branch to the end on success
t
# otherwise use a default value 
s/\\n.*$/ $((I))/
"
}

LIST="
alpha-third
alpha-seventh
alpha-first
alpha-eighth"

ORDERED_LIST=$(
    echo $LIST |
    tr ' ' '\n' |
    st |
    sort -k2,2n |
    awk '{print $1}')

echo unordered: $LIST
echo ordered:   $ORDERED_LIST

No comments: