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)
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
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
+++ /dev/null
-#!/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;
-}
--- /dev/null
+#!/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";
+}
-moreutils (0.5) UNRELEASED; urgency=low
+moreutils (0.5) unstable; urgency=low
* Added ifdata, by Benjamin BAYART (originally called ifcfg).
* Made ifdata -Wall clean.
* 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
- 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
+++ /dev/null
-#!/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;