#!/usr/bin/perl # usConstitutionSearch: # This script allows you to search the text of the US constitution # (as provided by http://www.usconstitution.net/const.txt) # for a search term (can be a regular expression if you like). # It expects at least one command-line argument specifying the search term. # It shows the matching lines with a few lines of context before and after. # You can specify how many lines of context are shown via the (optional) # second command-line argument (an integer). By default, 2 lines of context # are shown. # Examples of use: # usConstitutionSearch religion # usConstitutionSearch amendment 5 # usConstitutionSearch people 0 # # Cameron Hayne (macdev@hayne.net) April 2011 use strict; use warnings; use LWP::Simple; die "usage: $0 searchTerm [numContextLines]\n" unless @ARGV >= 1; my $searchTerm = shift @ARGV; my $numContextLines = (@ARGV ? shift @ARGV : 2); # get the text of the document: my $url = "http://www.usconstitution.net/const.txt"; my $contents = get($url) or die "Failed to download from $url: $!"; my @lines = split(/\r?\n/, $contents); my $numLines = scalar(@lines); my $start = "We the People"; my $startLineNum = -1; # find the matching lines: my %lineNums; for (my $i = 0; $i < $numLines; $i++) { $_ = $lines[$i]; if ($startLineNum < 0) { if (/^\s*$start/oi) { $startLineNum = $i; } else { next; # skip lines before the start } } if (/$searchTerm/oi) { $lineNums{$i} = 1; } } # fill in context lines: for my $lineNum (keys(%lineNums)) { for (my $i = 1; $i <= $numContextLines; $i++) { $lineNums{$lineNum - $i} = 1 if ($lineNum - $i) >= $startLineNum; $lineNums{$lineNum + $i} = 1 if ($lineNum + $i) < $numLines; } } # show the matching lines (with context) for my $lineNum (sort {$a <=> $b} keys %lineNums) { print "$lines[$lineNum]\n"; print "--------------------------\n" unless $lineNums{$lineNum + 1}; }