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