#!/usr/bin/perl
=begin metadata
Name: comm
Description: select or reject lines common to two files
Author: Mark-Jason Dominus, mjd-perl-comm@plover.comm
License: public domain
=end metadata
=cut
#
# comm
#
# 1999 M-J. Dominus (mjd-perl-comm@plover.com)
# Public domain.
#
use strict;
use File::Basename qw(basename);
use Getopt::Std qw(getopts);
use constant EX_SUCCESS => 0;
use constant EX_FAILURE => 1;
my $Program = basename($0);
my %opt;
getopts('123', \%opt) or usage();
usage() if (@ARGV != 2);
my @COL = (undef, !$opt{'1'}, !$opt{'2'}, !$opt{'3'});
my ($f1, $f2);
if ($ARGV[0] eq '-') {
if ($ARGV[1] eq '-') {
warn "$Program: only one file argument may be stdin\n";
exit EX_FAILURE;
}
$f1 = *STDIN;
} else {
if (-d $ARGV[0]) {
warn "$Program: '$ARGV[0]' is a directory\n";
exit EX_FAILURE;
}
unless (open $f1, '<', $ARGV[0]) {
warn "$Program: Couldn't open file '$ARGV[0]': $!\n";
exit EX_FAILURE;
}
}
if ($ARGV[1] eq '-') {
$f2 = *STDIN;
} else {
if (-d $ARGV[1]) {
warn "$Program: '$ARGV[1]' is a directory\n";
exit EX_FAILURE;
}
unless (open $f2, '<', $ARGV[1]) {
warn "$Program: Couldn't open file '$ARGV[1]': $!\n";
exit EX_FAILURE;
}
}
my $r1 = <$f1>;
my $r2 = <$f2>;
while (defined $r1 && defined $r2) {
if ($r1 eq $r2) {
print "\t\t", $r1 if $COL[3];
$r1 = <$f1>;
$r2 = <$f2>;
} elsif ($r1 gt $r2) {
print "\t", $r2 if $COL[2];
$r2 = <$f2>;
} else {
print $r1 if $COL[1];
$r1 = <$f1>;
}
}
print $r1 if defined $r1 && $COL[1];
print "\t", $r2 if defined $r2 && $COL[2];
if ($COL[1]) { print while <$f1> }
if ($COL[2]) { print "\t", $_ while <$f2> }
close $f1;
close $f2;
exit EX_SUCCESS;
sub usage {
warn "usage: $Program [-123] file1 file2\n";
exit EX_FAILURE;
}
__END__
=encoding utf8
=head1 NAME
comm - select or reject lines common to two files