How can I print the lines in STDIN in random order in Perl? How can I print the lines in STDIN in random order in Perl? unix unix

How can I print the lines in STDIN in random order in Perl?


I bet real Perl hackers will tear this apart, but here it goes nonetheless.

use strict;use warnings;use List::Util 'shuffle';my @lines = ();my $bufsize = 512;while(<STDIN>) {    push @lines, $_;    if (@lines == $bufsize) {        print shuffle(@lines);        undef @lines;    }}print shuffle(@lines);

Difference between this and the other solution:

  • Will not consume all the input and then randomize it (memory hog), but will randomize every $bufsize lines (not truly random and slow as a dog compared to the other option).
  • Uses a module which returns a new list instead of a in place editing Fisher - Yates implementation. They are interchangeable (except that you would have to separate the print from the shuffle). For more information type perldoc -q rand on your shell.


This perl snippet does the trick :

#! /usr/bin/perl# randomize cat# fisher_yates_shuffle code copied from Perl Cookbook # (By Tom Christiansen & Nathan Torkington; ISBN 1-56592-243-3)use strict;my @lines = <>;fisher_yates_shuffle( \@lines );    # permutes @array in placeforeach my $line (@lines) {    print $line;}# fisher_yates_shuffle( \@array ) : generate a random permutation# of @array in placesub 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];    }}__END__


use List::Util 'shuffle';print shuffle <>

Or if you worry about last lines lacking \n,

chomp(my @lines = <>);print "$_\n" for shuffle @lines;