Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting unique random line (at each script run) from an text file with perl

Tags:

perl

Having an text file like the next one called "input.txt"

some field1a | field1b | field1c
...another approx 1000 lines....
fielaNa | field Nb | field Nc

I can choose any field delimiter.

Need a script, what at every discrete run will get one unique (never repeated) random line from this file, until used all lines.

My solution: I added one column into a file, so have

0|some field1a | field1b | field1c
...another approx 1000 lines....
0|fielaNa | field Nb | field Nc

and processing it with the next code:

use 5.014;
use warnings;
use utf8;
use List::Util;
use open qw(:std :utf8);
my $file = "./input.txt";

#read all lines into array and shuffle them
open(my $fh, "<:utf8", $file);
my @lines = List::Util::shuffle map { chomp $_; $_ } <$fh>;
close $fh;

#search for the 1st line what has 0 at the start
#change the 0 to 1
#and rewrite the whole file

my $random_line;
for(my $i=0; $i<=$#lines; $i++) {
    if( $lines[$i] =~ /^0/ ) {
        $random_line = $lines[$i];
        $lines[$i] =~ s/^0/1/;
        open($fh, ">:utf8", $file);
        print $fh join("\n", @lines);
        close $fh;
        last;
    }
}
$random_line = "1|NO|more|lines" unless( $random_line =~ /\w/ );

do_something_with_the_fields(split /\|/, $random_line))
exit;

It is an working solution, but not very nice one, because:

  • the line order is changing at each script run
  • not concurrent script-run safe.

How to write it more effective and more elegantly?

like image 907
novacik Avatar asked Jul 23 '12 12:07

novacik


1 Answers

What about keeping a shuffled list of the line numbers in a different file, removing the first one each time you use it? Some locking might be needed to asure concurent script-run safety.

like image 116
choroba Avatar answered Sep 27 '22 22:09

choroba