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

前端 未结 3 1779
遇见更好的自我
遇见更好的自我 2020-12-17 06:17

I want to do the inverse of sort(1) : randomize every line of stdin to stdout in Perl.

相关标签:
3条回答
  • 2020-12-17 06:46

    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 place
    foreach my $line (@lines) {
        print $line;
    }
    
    # fisher_yates_shuffle( \@array ) : generate a random permutation
    # of @array in place
    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];
        }
    }
    
    __END__
    
    0 讨论(0)
  • 2020-12-17 07:01

    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.
    0 讨论(0)
  • 2020-12-17 07:01
    use List::Util 'shuffle';
    print shuffle <>
    

    Or if you worry about last lines lacking \n,

    chomp(my @lines = <>);
    print "$_\n" for shuffle @lines;
    
    0 讨论(0)
提交回复
热议问题