Wednesday, January 8, 2014

Numerical Sorting with the Bash Shell

This post will  explain the use of the sort utility while in the Bash shell.  The Sort utility can be used with output or on a text file. Open up an X11 terminal and make sure you are at a Bash shell prompt (type 'bash'). Use the man command to look at the following commands:

sort : Cygwin, Linux, BSD and MAC
seq : Cygwin or Linux only
shuf : Cygwin or Linux oly
jot : BSD or MAC only
awk : Cygwin, Linux, BSD and MAC


First we are going to use 'seq' and 'shuf' to create a random list of numbers:

seq 1 100 | shuf
94
32
39
61
17
84
6
77
18
58
29

...

Then we are going to perform a numerical sort:

seq 1 100 | shuf | sort -n
1
2
3
4
5
6
7
8
9
10

We don't have 'seq' and 'shuf' on MAC or BSD. However, 'jot' is more versatile:

 jot 10 0 10000 1
0
1
2
3
4
5
6
7
8
9

Now we use a random  'jot' but sort the output. The default is an alpha sort:
jot -r 10 0 10000 1 | sort 
jot: random seeding not supported
3462
4537
520
5288
5366
5525
7321
7487
8639
9425

Now we apply a numerical sort:

jot -r 10 0 10000 1 | sort -n
jot: random seeding not supported
4645
4751
5095
6384
6560
8136
8412
9593
9684
9772

The Bash shell maintain a $RANDOM variable. So we can use $RANDOM in for loops to create lists:

for I in {1..10}; do echo $RANDOM; done | sort -n
1085
5637
6540
8175
13029
18256
21983
26225
27581
29007

for I in $(seq 1 10); do echo $RANDOM; done | sort -n
4002
5001
5311
8311
10374
12789
13139
13263
16935
28382

for I in $(jot 10 0 10000 1); do echo $RANDOM; done | sort -n
1469
5367
7976
10735
16442
17531
21028
24238
25302
30346

Something similar can be done with an a to z list in Cygwin or Linux:

 for I in {a..z}; do  echo $I;  done >> a2z.txt

shuf a2z.txt
e
p
n
w
z
m
b
f
y
...

 shuf a2z.txt | sort
a
b
c
d
e
f
g
h
i
j
k
...


These are two shell scripts which will create random number ranges which can be sorted or redirected to a file for sorting. Remember to run 'chmod +x' on the shell file to make it executable before executing from the shell.

# create text file random.sh; 'chmod +x random.sh; ./random.sh | sort -n
#!/bin/bash
random()
{
    local range=${1:-1}

    RAND=`echo $RANDOM | awk '{print $1}'`
    let "RAND=$RAND%($range+1)"
}
n=100
while [ $(( n -=1 )) -ge "0" ]; do
    random 100
    echo "$RAND"
done


# create text file rand.sh; 'chmod +x rand.sh; ./rand.sh | sort -n
#!/bin/bash
random()
{
    local range=${1:-1}

    RAND=`od -t uI -N 4 /dev/urandom | awk '{print $2}'`
    let "RAND=$RAND%($range+1)"
}
n=100
while [ $(( n -=1 )) -ge "0" ]; do
    random 100
    echo "$RAND"
done

No comments:

Post a Comment