initial commit
This commit is contained in:
commit
4c2a91533d
|
@ -0,0 +1,20 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright 2020 "yafox"
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,36 @@
|
||||||
|
shsort
|
||||||
|
======
|
||||||
|
|
||||||
|
a recursive quicksort in pure posix shell script using any arbitrary function
|
||||||
|
or command capable of parsing a comparison expression and outputing "yes" or
|
||||||
|
"no." (e.g., anything that takes a string in the form of "1 > 3" as a command
|
||||||
|
line argument and echoes "no" and takes "1 < 3" and echoes "yes".)
|
||||||
|
|
||||||
|
34 SLOC.
|
||||||
|
|
||||||
|
usage: shsort [-r] <comparator command> [<list>]
|
||||||
|
|
||||||
|
shsort expects a newline delimited list of elements to sort. the list may be
|
||||||
|
passed via stdin in or on the command line as the <list> argument.
|
||||||
|
|
||||||
|
the comparator command is used as-is and may be a string including flags.
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
$ printf "2.9\n1.2\n3.4\n2.1\n2.1-rc0\n2.12" | shsort "vercmp -f default"
|
||||||
|
3.4
|
||||||
|
2.12
|
||||||
|
2.9
|
||||||
|
2.1
|
||||||
|
2.1-rc0
|
||||||
|
1.2
|
||||||
|
|
||||||
|
`-r` reverses the sort order:
|
||||||
|
|
||||||
|
$ printf "2.9\n1.2\n3.4\n2.1\n2.1-rc0\n2.12" | shsort -r "vercmp -f default"
|
||||||
|
1.2
|
||||||
|
2.1-rc0
|
||||||
|
2.1
|
||||||
|
2.9
|
||||||
|
2.12
|
||||||
|
3.4
|
|
@ -0,0 +1,9 @@
|
||||||
|
SRCDIR = $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
|
PREFIX ?= /usr
|
||||||
|
DESTDIR ?= $(PREFIX)/bin
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp -a $(SRCDIR)/shsort.sh $(DESTDIR)/shsort
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm $(DESTDIR)/shsort
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
usage() { echo "usage: shsort [-r] <comparator> [<list>]" >&2 && exit 0; }
|
||||||
|
|
||||||
|
[ "$1" ] || usage
|
||||||
|
|
||||||
|
[ "$1" != "-r" ] || { rev="yes" && shift; }
|
||||||
|
|
||||||
|
cmpfn="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
quicksort() {
|
||||||
|
len="$(printf "$@\n" | wc -l)"
|
||||||
|
[ "$len" -gt 1 ] || { echo "$@" && return 0; }
|
||||||
|
|
||||||
|
pvtidx="$(expr $len / 2)"
|
||||||
|
pvt="$(printf "$@\n" | head -n$pvtidx | tail -n1)"
|
||||||
|
|
||||||
|
parted="$(printf "$@\n" | while read elem; do
|
||||||
|
{ [ "$elem" ] && [ "$elem" != "$pvt" ]; } || continue
|
||||||
|
[ "$($cmpfn "$elem < $pvt")" = "yes" ] \
|
||||||
|
&& printf "<\t$elem\n" \
|
||||||
|
|| printf ">\t$elem\n"
|
||||||
|
done)"
|
||||||
|
lesser="$(printf "$parted\n" | grep "^<" | cut -f2)"
|
||||||
|
greater="$(printf "$parted\n" | grep "^>" | cut -f2)"
|
||||||
|
|
||||||
|
if [ "$rev" ]; then
|
||||||
|
printf "%s\n%s\n%s\n" "$(quicksort "$lesser")" "$pvt" "$(quicksort "$greater")"
|
||||||
|
else
|
||||||
|
printf "%s\n%s\n%s\n" "$(quicksort "$greater")" "$pvt" "$(quicksort "$lesser")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$@" ]; then
|
||||||
|
elems="$@"
|
||||||
|
else
|
||||||
|
while read input; do
|
||||||
|
elems="$elems$input\n"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
[ "$elems" ] || usage
|
||||||
|
|
||||||
|
quicksort "$elems" | sed '/^$/d'
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# strip all trailing whitespace, then all leading whitespace, then all lines
|
||||||
|
# starting with '#', then all empty lines. then count the remaining lines.
|
||||||
|
sed 's/[[:space:]]*$//g; s/^[[:space:]]*//g; s/^#.*$//g; /^$/d' shsort.sh \
|
||||||
|
| wc -l - \
|
||||||
|
| cut -d' ' -f1
|
||||||
|
|
||||||
|
# note that this script's ELOC is NOT included in the count.
|
Loading…
Reference in New Issue