#! /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>;

