Shuffling shell input
While the Fisher-Yates shuffle sounds like 1920′s dance move, it is the standard method for shuffling larger arrays of data.
The below operates like a simple Unix filter taking an array of data (separated by newlines) and returning a quickly sorted output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/usr/bin/perl # Usage: cat file | shuffle # From: http://hash-bang.net/2009/04/shuffling-shell-inputshuffling-shell-input/ # Return a shuffled version of the input stream # Author: Matt Carter <m@ttcarter.com> sub fisher_yates_shuffle { my $array = shift; my $i; for ($i = @$array; --$i; ) { my $j = int rand ($i+1); next if $i == $j; @$array[$i,$j] = @$array[$j,$i]; } } while(<>) { chomp; push @input, $_; } &fisher_yates_shuffle(\@input); print join("\n",@input); |
For example:
ls | shuffle |
Returns a randomized list of files in the current directory.
had a play with this on my lenny box only to find that there is a command ‘shuf’ already installed (by default) that seems to do something similar.
nice though.
Yes I discoverd Shuf too after writing this article.
I really wish the package maintainers would add a few tags so things like this would show up in tools like ‘apropos’. ‘Shuf’ is all well and good but missing those last characters means people keep reinventing the wheel with the result above.