	#!/usr/bin/perl -w
02
	#-------------------------------------------------------------------------------
03
	# sample_records.pl -- Selects records at random from a file.
04
	#
05
	# This program is designed to randomly select slightly more records than
06
	# requested from a file. In most cases, the slightly larger record count is
07
	# perfectly acceptable. In cases where an exact count of records is desired,
08
	# a random sample with the exact number of records needed can be drawn from the
09
	# result file from this script, which is much more efficient than creating a
10
	# random sample with an exact number of records from the original full file.
11
	#
12
	# IMPORTANT NOTE: The records in the file created by this script are NOT in
13
	# random order (they have the same ordering that they have in the original
14
	# file), so if you need a random subsample of N records from this script's
15
	# result file, you CAN NOT just take the first N records. You MUST randomly
16
	# sample from the result file to get N records. If the script returned records
17
	# in a random order, you would be able to take the first N records to get a
18
	# truly random subsample. However, returning records in random order is
19
	# potentially slow and/or resource intensive, and this script was written to
20
	# select a random sample of records as efficiently as possible.
21
	#
22
	# This program requires a file with lines that are separated by carriage returns
23
	# or newline characters.
24
	#
25
	# Synopsis
26
	# --------
27
	# perl sample_file.pl file_name record_count sample_count
28
	# This writes the results to standard output, so you'll probably want to use
29
	# the > operator to send the results to a file in almost all cases.
30
	#
31
	# Arguments
32
	# ---------
33
	# All arguments are required.
34
	#
35
	# file_name
36
	# The name of the original file.
37
	#
38
	# record_count
39
	# The number of records in the original file.
40
	#
41
	# You can provide a smaller number than the actual record count (if,
42
	# for example, you don't know the exact record count), and the number of
43
	# selected records will still be greater than your requested count.
44
	#
45
	# sample_count
46
	# The desired number of records in your sample.
47
	#
48
	# Example Usage
49
	# -------------
50
	# perl sample_file.pl original_file.txt 1000000 10000 > sampled_file.txt
51
	# creates a new file called sampled_file.txt that contains a random sample of
52
	# approximately 10,000 records from the original file called
53
	# original_file.txt containing 1,000,000 records
54
	#-------------------------------------------------------------------------------
55
	 
56
	use strict;
57
	 
58
	my ($filename, $record_count, $sample_count) = @ARGV;
59
	 
60
	die 'no filename given' if not defined $filename;
61
	die 'no record count given' if not defined $record_count;
62
	die 'no sample count given' if not defined $sample_count;
63
	 
64
	open my $ip, '<', $filename or die "cannot open $filename: $!";
65
	 
66
	#-------------------------------------------------------------------------------
67
	# With this value of $epsilon, the probability of the selected record count
68
	# being greater than $sample_count is > 99%.
69
	#-------------------------------------------------------------------------------
70
	my $epsilon = 2.325/(2 * sqrt($record_count));
71
	#-------------------------------------------------------------------------------
72
	 
73
	while(<$ip>){
74
	print $_ if rand() <= $sample_count/$record_count + $epsilon;
75
	} 
