
![]() | ![]() |
8.6. Picking a Random Line from a File
8.6.1. Problem
You
want to return a random line from a file.
8.6.2. Solution
Use
rand and $. (the current line
number) to decide which line to print:srand;
rand($.) < 1 && ($line = $_) while <>;
# $line is the random line
8.6.3. Discussion
This is a beautiful example of a solution that may not be obvious. We
read every line in the file but don't have to store them all in
memory. This is great for large files. Each line has a 1 in N (where
N is the number of lines read so far) chance of being selected.Here's a replacement for fortune using this
algorithm:$/ = "%%\n";
@ARGV = ("/usr/share/games/fortunes") unless @ARGV;
srand;
rand($.) < 1 && ($adage = $_) while <>;
print $adage;
If you know line offsets (for instance, you've created an index) and
the number of lines, you can randomly select a line and jump to its
offset in the file, but you usually don't have such an index.Here's a more rigorous explanation of how the algorithm works. The
function call rand ($.) picks a
random number between 0 and the current line number. Therefore, you
have a one in N chance, that is,

first line because






directly proportional to the size of the file, but using no more
memory than it takes to hold the longest line, even in the worst
case.
8.6.4. See Also
The $. entry in perlvar(1)
and in Chapter 28 of Programming Perl; Recipe 2.6; Recipe 2.7
![]() | ![]() | ![]() |
8.5. Trailing a Growing File | ![]() | 8.7. Randomizing All Lines |

Copyright © 2003 O'Reilly & Associates. All rights reserved.