1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#! /usr/bin/perl
use warnings;
use strict;
use integer;
our $usage = <<END;
usage: $0 big small
(replace either filename with '-' for stdin)
END
# This script subtracts the contents of a "small" file from those of
# a "big." It outputs the difference. (Note: this script does not
# attempt to detect when the small file contains something the big file
# does not, nor does it require the small file actually to be smaller
# than the big. It merely reports lines in the big file which the small
# lacks.)
#
# This script does not respond to options---not even to -h. However, if
# you invoke it without an argument it will exit with an error and print
# to stderr a usage message.
# Preliminaries.
@ARGV == 1 || @ARGV == 2 or die $usage;
my $big = shift;
my $small = shift;
defined $small or $small = '-';
$big ne '-' or $small ne '-'
or die "$0: stdin cannot be both big and small\n";
my( $fh_big, $fh_small );
for (
{ filename => \$big , fh => \$fh_big },
{ filename => \$small, fh => \$fh_small },
) {
if ( ${ $_->{filename} } eq '-' ) { ${ $_->{fh} } = \*STDIN }
else { open ${ $_->{fh} }, '<', ${ $_->{filename} } }
}
# Here is the main program. In Perl, it is very short.
my %small = map {$_=>1} <$fh_small>;
print for grep { !$small{$_} } <$fh_big>;
|