From 4671f67156c1c59c2f9f7c3ead1a2e9141375d41 Mon Sep 17 00:00:00 2001 From: joeyh Date: Wed, 8 Mar 2006 04:04:34 +0000 Subject: [PATCH] * Replaced and(1) and not(1) by combine, based on an idea by Matt Taggart. --- Makefile | 4 +- README | 21 +------- and | 50 ----------------- combine | 137 +++++++++++++++++++++++++++++++++++++++++++++++ debian/changelog | 6 +-- debian/control | 3 +- not | 57 -------------------- 7 files changed, 145 insertions(+), 133 deletions(-) delete mode 100755 and create mode 100755 combine delete mode 100755 not 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 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 first reads standard input, and compares it with the specified file. - -=head1 AUTHOR - -Copyright 2006 by Joey Hess - -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 () { - 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 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 + +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 () { + 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 Tue, 7 Mar 2006 21:54:45 -0500 + -- Joey Hess 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 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 first reads -standard input, and compares it with the specified file. - -=head1 AUTHOR - -Copyright 2006 by Joey Hess - -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 () { - chomp; - $seen{$_}++; - } - close IN; -} - - -open (IN, $first) || die "and: read $first: $!\n"; -while () { - chomp; - print "$_\n" if ! $seen{$_}; -} -close IN; -- 2.39.5