Download shuffle.awk
#!/bin/awk -f

### shuffle.awk --- Shuffle lines in a file

## Copyright (C) 2007  Aaron S. Hawley <aaronh@localhost>

## Author: Aaron S. Hawley
## Keywords: random, games

## This program is free software: you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation, either version 3 of
## the License, or (at your option) any later version.

## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.

## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.

## $Id: shuffle.awk,v 1.2 2007/08/09 13:58:22 aaronh Exp $

### Commentary:

## This awk script will shuffle the lines in a file randomly.

### Example:

## $ seq 1 7  | awk -f shuffle.awk
## 4
## 1
## 6
## 2
## 5
## 3
## 7

### Code:


BEGIN {
    srand();
}

{
    l[NR] = $0;
}

END {
    for (i = 1; i <= NR; i++) {
        n = int(rand() * (NR - i + 1)) + i;
        #print "rand_between(" i ", " NR") => " n;
        print l[n];
        #print "swap line " i " for line " n;
        l[n] = l[i];
    }
}

## Test suite:
# seq 1 100 | awk -f ./shuffle.awk | wc -l #=> 100
# f="1 2 3"; while [ "$(echo ${f})" != "3 1 2" ]; do f=$(seq 1 3 | ./shuffle.awk); done; echo ${f}; #=> 3 1 2
# f="3 1 2"; while [ "$(echo ${f})" != "2 3 1" ]; do f=$(seq 1 3 | ./shuffle.awk); done; echo ${f}; #=> 2 3 1
# f="2 3 1"; while [ "$(echo ${f})" != "3 2 1" ]; do f=$(seq 1 3 | ./shuffle.awk); done; echo ${f}; #=> 3 2 1
# f="3 2 1"; while [ "$(echo ${f})" != "1 3 2" ]; do f=$(seq 1 3 | ./shuffle.awk); done; echo ${f}; #=> 1 3 2
# f="1 3 2"; while [ "$(echo ${f})" != "2 1 3" ]; do f=$(seq 1 3 | ./shuffle.awk); done; echo ${f}; #=> 2 1 3
# f="2 1 3"; while [ "$(echo ${f})" != "1 2 3" ]; do f=$(seq 1 3 | ./shuffle.awk); done; echo ${f}; #=> 1 2 3