summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--README21
-rwxr-xr-xand50
-rwxr-xr-xcombine137
-rw-r--r--debian/changelog6
-rw-r--r--debian/control3
-rwxr-xr-xnot57
7 files changed, 145 insertions, 133 deletions
diff --git a/Makefile b/Makefile
index 78d111c..7cacd7e 100644
--- 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 2aeaa88..a69a6ec 100644
--- 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
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
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";
+}
diff --git a/debian/changelog b/debian/changelog
index e563801..9eeedd9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -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
diff --git a/debian/control b/debian/control
index 44b6d2d..d0c752e 100644
--- a/debian/control
+++ b/debian/control
@@ -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
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;