Subject: Re: Juggling Lines Mon Apr 27 09:53:54 1998 >I have a text file with 100 lines. What is the best and easiest way to >juggle the lines in that file so that it lists the lines randomly? the perl for that is pretty simple, and i'm bored this morning.. here are a few variants which accept input in various ways. hypothetical typos aside, they should do what you're looking for. the progression can be seen as a series of archaeological strata in a program's development for those of you who are interested in learning to program, or just have to deal with programmers and wonder how they got that way.. for the first one, you just paste the lines you want to shuffle into the end of the file: ---- local_shuffle.pl ---- #!/usr/local/bin/perl srand (time); @old_order = ; @new_order = (); for $item (@old_order) { $pos = rand (@new_order); push @new_order, $new_order[$pos]; $new_order[$pos] = $item; } print @new_order; __END__ paste list of data here . . . ---- EOF ---- the second one will open a file, shuffle it, and print the results: ---- file_shuffle.pl ---- #!/usr/local/bin/perl srand (time); $file = "/some_path/to_a/file.txt"; open (FILE, $file) or die qq(can't read "$file": $!); @old_order = ; close FILE; @new_order = (); for $item (@old_order) { $pos = rand (@new_order); push @new_order, $new_order[$pos]; $new_order[$pos] = $item; } print @new_order; ---- EOF ---- the third one will take the name of the file as a command-line argument. if it doesn't see a valid filename on the command line, it will prompt you to enter one: ---- cmdline_shuffle.pl ---- #!/usr/local/bin/perl srand (time); $file = &prompt_for_file( $ARGV[0] ); open (FILE, $file) or die qq(can't read "$file": $!); @old_order = ; close FILE; @new_order = (); for $item (@old_order) { $pos = rand (@new_order); push @new_order, $new_order[$pos]; $new_order[$pos] = $item; } print @new_order; sub prompt_for_file { @MSG = ( "no filename given on command-line.", "sorry, that file does not exist.", ); my $file = shift; my $m = 0; while ( ! -f $file) { print $MSG[$m], "\n"; $m = 1; print "which file would you like to shuffle? : "; $file = <>; chop $file; } return ($file); } ---- EOF ---- and the final version will handle files which are too large to hold in memory all at once. it takes two filenames as command-line arguments, one for input, one for output; or prompts for them when it needs them: (minor point: if the target file already exists, it will ask if you want to overwrite it. this is a laid-back program, though, and will take anything beginning with 'y' as approval.. 'yes', 'yeah', 'yep', 'you betcha'.. whatever) ---- large_shuffle.pl ---- #!/usr/local/bin/perl srand (time); $file = &prompt_for_file( $ARGV[0] ); open (FILE, $file) or die qq(can't read "$file": $!); @old_order = (0); while () { push @old_order, tell FILE; } @new_order = (); for $item (@old_order) { $pos = rand (@new_order); push @new_order, $new_order[$pos]; $new_order[$pos] = $item; } $new_file = &get_new_filename ($ARGV[1]); open (DST, ">$new_file") or die qq(can't write to "$new_file": $!); for $pos (@new_order) { seek (FILE, $pos, 0); $line = ; print DST $line; } close DST; close FILE; sub prompt_for_file { @MSG = ( "no filename given on command-line.", "sorry, that file does not exist.", ); my $file = shift; my $m = 0; while ( ! -f $file) { print $MSG[$m], "\n"; $m = 1; print "which file would you like to shuffle? : "; $file = <>; chop $file; } return ($file); } sub get_new_filename { my $file = shift; while (($file !~ /\w/) || (-f $file)) { if (-f $file) { print qq("$file" already exists.. overwrite it? [y/n] : ); $y_n = <>; chop $y_n; last if ($y_n =~ /^y/); } print "where would you like to write the output? : "; $file = <>; chop $file; } return ($file); } ---- EOF ----