]> err.no Git - moreutils/commitdiff
* Replaced and(1) and not(1) by combine, based on an idea by Matt Taggart.
authorjoeyh <joeyh>
Wed, 8 Mar 2006 04:04:34 +0000 (04:04 +0000)
committerjoeyh <joeyh>
Wed, 8 Mar 2006 04:04:34 +0000 (04:04 +0000)
Makefile
README
and [deleted file]
combine [new file with mode: 0755]
debian/changelog
debian/control
not [deleted file]

index 78d111c0515155531a55cdf3bba9fc0dcc60a6ce..7cacd7e06e6d90936f455b4d300e79a7e5a65cd5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 BINS=isutf8 sponge ifdata
-PERLSCRIPTS=vidir vipe ts and not
-MANS=sponge.1 vidir.1 vipe.1 isutf8.1 ts.1 and.1 not.1 ifdata.1
+PERLSCRIPTS=vidir vipe ts combine
+MANS=sponge.1 vidir.1 vipe.1 isutf8.1 ts.1 combine.1 ifdata.1
 CFLAGS=-O2 -g -Wall
 
 all: $(BINS) $(MANS)
diff --git a/README b/README
index 2aeaa88a2e4c4a89a76268255dafab8eb1293274..a69a6ec9a570f2d2894867c5736da3d7a765e437 100644 (file)
--- a/README
+++ b/README
@@ -11,10 +11,8 @@ vidir
        edit a directory in your text editor
 vipe
        edit a pipe using your text editor
-and
-       print lines that are present in one file and another
-not
-       print lines that are present in one file but not another
+combine
+       combine the lines in two files using boolean operations
 ifdata
        get network interface info without parsing ifconfig output
 
@@ -23,21 +21,6 @@ Your suggestions of additional tools to add to this collection are
 apprecitated. Here are some that are under consideration but have not yet
 been included, I also welcome feedback on which of these to include.
 
-_
-       Matt Taggart suggests that and(1) and not(1) be integrated into one
-       utility taking a page from test(1)/[. It would work like this:
-
-       _ file1 and file2
-       _ file1 not file2
-
-       Where any file can be "-" for stdin. Could also add "or", "xor",
-       etc to this. This makes it much clearer which file is on which side
-       of the boolean expression.
-
-       If it's called "_" that should probably be an alias for something
-       longer, such as lcombine. What exactly to call it is the unresolved
-       question -- is "_" something moreutils can justify taking for this?
-
 mime
        determines the mime type of a file using the gnome mine database
 
diff --git a/and b/and
deleted file mode 100755 (executable)
index 4165410..0000000
--- a/and
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/perl
-
-=head1 NAME
-
-and - print lines that are present in one file and another
-
-=head1 SYNOPSIS
-
-and file
-
-and [file|-] [file|-] ...
-
-=head1 DESCRIPTION
-
-B<and> reads the specified files and prints out the lines that are common
-to all files, in the order they are listed in the last file. Use "-" to
-make it read a file from standard input. If only one file is specified,
-B<and> first reads standard input, and compares it with the specified file.
-
-=head1 AUTHOR
-
-Copyright 2006 by Joey Hess <joey@kitenet.net>
-
-Licensed under the GNU GPL.
-
-=cut
-
-use warnings;
-use strict;
-
-if (@ARGV == 0) {
-       die "usage: and [file|-] [file|-] ...\n";
-}
-
-if (@ARGV == 1) {
-       unshift @ARGV, "-";
-}
-
-my %seen;
-foreach my $fn (@ARGV) {
-       open (IN, $fn) || die "and: read $fn: $!\n";
-       while (<IN>) {
-               chomp;
-               $seen{$_}++;
-               if ($seen{$_} == @ARGV) {
-                       print "$_\n";
-               }
-       }
-       close IN;
-}
diff --git a/combine b/combine
new file mode 100755 (executable)
index 0000000..ad61f52
--- /dev/null
+++ b/combine
@@ -0,0 +1,137 @@
+#!/usr/bin/perl
+
+=head1 NAME
+
+combine - combine the lines in two files using boolean operations
+
+=head1 SYNOPSIS
+
+combine file1 and file2
+
+combine file1 not file2
+
+combine file1 or file2
+
+combine file1 xor file2
+
+_ file1 and file2 _
+
+_ file1 not file2 _
+
+_ file1 or file2 _
+
+_ file1 xor file2 _
+
+=head1 DESCRIPTION
+
+B<combine> conbines the lines in two files. Depending on the boolean
+operation specified, the contents will be combined in different ways:
+
+=over 4
+
+=item and
+
+Outputs lines that are common to both files.
+
+=item not
+
+Outputs lines that are in file1 but not in file2.
+
+=item or
+
+Outputs lines that are in file1 or file2.
+
+=item xor
+
+Outputs lines that are in either file1 or file2, but not in both files.
+
+=back
+
+"-" can be specified for either file to read stdin for that file.
+
+The input files need not be sorted, and the lines are output in the order
+they accur in file1 (or file2 for the two "or" operations).
+
+Note that this program can be installed as "_" to allow for the syntactic
+sugar shown in the latter half of the synopsis (similar to the test/[
+command). It is not currently installed as "_" by default.
+
+=head1 AUTHOR
+
+Copyright 2006 by Joey Hess <joey@kitenet.net>
+
+Licensed under the GNU GPL.
+
+=cut
+
+use warnings;
+use strict;
+
+sub filemap {
+       my $file=shift;
+       my $sub=shift;
+
+       open (IN, $file) || die "$file: $!\n";
+       while (<IN>) {
+               chomp;
+               $sub->();
+       }
+       close IN;
+}
+
+sub hashify {
+       my $file=shift;
+
+       my %seen;
+       filemap $file, sub { $seen{$_}++ };
+       return \%seen;
+}
+
+sub compare_or {
+       my ($file1, $file2) = @_;
+
+       my $seen;
+       filemap $file1, sub { print "$_\n"; $seen->{$_}++ };
+       filemap $file2, sub { print "$_\n" unless $seen->{$_} };
+}
+
+sub compare_xor {
+       my ($file1, $file2) = @_;
+       
+       compare_not($file1, $file2);
+       compare_not($file2, $file1);
+}
+
+sub compare_not {
+       my ($file1, $file2) = @_;
+
+       my $seen=hashify($file2);
+       filemap $file1, sub { print "$_\n" unless $seen->{$_} };
+}
+
+sub compare_and {
+       my ($file1, $file2) = @_;
+
+       my $seen=hashify($file2);
+       filemap $file1, sub { print "$_\n" if $seen->{$_} };
+}
+
+if (@ARGV >= 4 && $ARGV[3] eq "_") {
+       delete $ARGV[3];
+}
+
+if (@ARGV != 3) {
+       die "usage: combine file1 OP file2\n";
+}
+
+my $file1=shift;
+my $op=shift;
+my $file2=shift;
+
+if ($::{"compare_$op"}) {
+       no strict 'refs';
+       "compare_$op"->($file1, $file2);
+}
+else {
+       die "unknown operation, $op\n";
+}
index e56380100b3af34e69ca9b6b499f7cfdaa2b34d6..9eeedd926818acfe2a331fe0d4f709dc143c35c3 100644 (file)
@@ -1,4 +1,4 @@
-moreutils (0.5) UNRELEASED; urgency=low
+moreutils (0.5) unstable; urgency=low
 
   * Added ifdata, by Benjamin BAYART (originally called ifcfg).
   * Made ifdata -Wall clean.
@@ -6,9 +6,9 @@ moreutils (0.5) UNRELEASED; urgency=low
   * Cleaned up ifdata's behavior when asked to print info for nonexistant
     devices. Still needs improvement.
   * Indentation improvements.
-  * README updates based on user feedback.
+  * Replaced and(1) and not(1) by combine, based on an idea by Matt Taggart.
 
- -- Joey Hess <joeyh@debian.org>  Tue,  7 Mar 2006 21:54:45 -0500
+ -- Joey Hess <joeyh@debian.org>  Tue,  7 Mar 2006 23:02:14 -0500
 
 moreutils (0.4) unstable; urgency=low
 
index 44b6d2d1c625003b80214a4d1ec9bde23e1a38fc..d0c752e7960500877159f45b886a3e01ae6cb844 100644 (file)
@@ -18,6 +18,5 @@ Description: additional unix utilities
   - ts: timestamp standard input
   - vidir: edit a directory in your text editor
   - vipe: edit a pipe using your text editor
-  - and: print lines that are present in one file and another
-  - not: print lines that are present in one file but not another
+  - combine: combine the lines in two files using boolean operations
   - ifdata: get network interface info without parsing ifconfig output 
diff --git a/not b/not
deleted file mode 100755 (executable)
index c67467c..0000000
--- a/not
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/perl
-
-=head1 NAME
-
-not - print lines that are present in one file but not another
-
-=head1 SYNOPSIS
-
-not file
-
-not [file|-] [file|-] ...
-
-=head1 DESCRIPTION
-
-B<not> reads the specified files and prints out the lines that are present
-in the first but not in subsequent files. Use "-" to make it read a file
-from standard input. If only one file is specified, B<not> first reads
-standard input, and compares it with the specified file.
-
-=head1 AUTHOR
-
-Copyright 2006 by Joey Hess <joey@kitenet.net>
-
-Licensed under the GNU GPL.
-
-=cut
-
-use warnings;
-use strict;
-
-if (@ARGV == 0) {
-       die "usage: not [file|-] [file|-] ...\n";
-}
-
-if (@ARGV == 1) {
-       unshift @ARGV, "-";
-}
-
-my $first=shift;
-
-my %seen;
-foreach my $fn (@ARGV) {
-       open (IN, $fn) || die "and: read $fn: $!\n";
-       while (<IN>) {
-               chomp;
-               $seen{$_}++;
-       }
-       close IN;
-}
-
-
-open (IN, $first) || die "and: read $first: $!\n";
-while (<IN>) {
-       chomp;
-       print "$_\n" if ! $seen{$_};
-}
-close IN;