#!/usr/bin/perl # # randomize [-v#] file... > random_file # # Simple perl program to completely randomize the order of the # lines of all the files given. Using the Fisher-Yates Algorithm # # Options: -v Output lines to both outut and error channels # -# Limit the number of lines to output # # See also "shuf", the GNU equivelent # ### # # Anthony Thyssen (September 2005) # use strict; use FindBin; my $PROGNAME = $FindBin::Script; sub Error { print STDERR "$PROGNAME: ", @_, "\n"; exit 1 } sub Usage { print STDERR @_, "\n" if @_; @ARGV = ( "$FindBin::Bin/$PROGNAME" ); while( <> ) { next if 1 .. 2; last if /^###/; s/^#$//; s/^# //; last if /^$/; print STDERR $. == 3 ? "Usage: $_" : " $_"; } print STDERR "For full manual use --help\n"; exit 10; } sub Help { @ARGV = ( "$FindBin::Bin/$PROGNAME" ); while( <> ) { next if $. == 1; last if /^###/; s/^#$//; s/^# //; print STDERR; } exit 10; } my $lines = 0; # output all the lines in the file my $verbose = 0; OPTION: # Multi-switch option handling while( @ARGV && $ARGV[0] =~ s/^-(?=.)// ) { $_ = shift; { m/^$/ && do { next }; # Next option m/^-$/ && do { last }; # End of options '--' m/^\?/ && do { Help }; # Usage Help '-?' m/^-?(help|doc|man|manual)$/ && Help; # Print help manual comments s/^(\d+)// && do { $lines = $1; redo }; # number of lines s/^v// && do { $verbose++; redo }; # output to stderr too Usage( "$PROGNAME: Unknown Option \"-$_\"" ); } continue { next OPTION }; last OPTION; } # ---------------------------------------- srand($$^time); my @lines = <>; # read in all lines into memory # print a random line, and delete, repeat until no more lines. while( $#lines >= 0 ) { my $line = splice(@lines, rand(@lines)+$[, 1); print $line; print STDERR $line if $verbose; last if --$lines == 0; }