#!/usr/bin/perl

=begin metadata

Name: paste
Description: merge corresponding or subsequent lines of files
Author: Randy Yarger, randy.yarger@nextel.com
License: perl

=end metadata

=cut


use strict;
no strict 'refs';

my ($VERSION) = '1.2';

my @fh;

my @sep = ( "\t" );
my $dash_ess = 0;

while ($ARGV[0] =~ /^-.+$/) {
	$_ = shift @ARGV;
	/^-\?$/ and do { print <<EOF;
Usage: $0 [-s] [-d list] [file...]

Merges the corresponding lines of files.
EOF
		exit;
	};
	/^-d$/ and do {
		my $arg = shift;
		@sep = split(//, eval qq{sprintf("$arg")});
		next;
	};
	/^-s$/ and do { $dash_ess = 1; next; }
}

if (@ARGV) {
	for my $i (0..$#ARGV) {
		$fh[$i] = "F$i";
		open($fh[$i], '<', $ARGV[$i]) or die "$0: cannot open $ARGV[$i]";
	}
} else {
	$fh[0] = \*STDIN;
}

if ($dash_ess) {
	for my $i (0..$#fh) {
		my $fh;
		$fh = $fh[$i];
		my $current_sep = 0;
		my $tline;
		while(<$fh>) {
			chomp;
			$tline .= $_ . $sep[$current_sep++];
			$current_sep = 0 if $current_sep == scalar @sep;
		}
		chop $tline;
		print "$tline\n";
		close $fh;
	}
	exit;
}

my $files_still_open = 1;
while (1) {
	my $current_sep = 0;
	$files_still_open = 0;
	for my $i (0..$#fh) {
		$files_still_open = 1 if not eof $fh[$i];
	}
	last if not $files_still_open;

	my $tline;
	for my $i (0..$#fh) {
		if (not eof $fh[$i]) {
			my $fh;
			$fh = $fh[$i];
			my $line = <$fh>;
			chomp($line);
			$tline .= $line;
		}
		$tline .= "$sep[$current_sep++]" if $i != $#fh;
		$current_sep = 0 if $current_sep == scalar @sep;
	}
	print "$tline\n";
}

__END__

=pod

=head1 NAME

paste - merge corresponding or subsequent lines of files

=head1 SYNOPSIS

paste [-s] [-d list] [file...]

=head1 DESCRIPTION

Paste combines the corresponding lines of multiple files. Each line of each
file is printed seperated by tab (or by the characters listed in the -d
option).  If no files are specified, stdin is read.

=head2 OPTIONS

I<paste> accepts the following options:

=over 4

=item -d list

Define the column delimiters. Each character in this list will be used
one at a time, as a delimiter for the columns. If there are fewer characters
than columns, the characters will be repeated. Standard Perl special characters
("\n", "\t", etc.) are recognized.

=item -s

Displays the output one file per row, rather than interleaving the
lines of the files.

=back

=head1 ENVIRONMENT

The working of I<paste> is not influenced by any environment variables.

=head1 BUGS

I<paste> has no known bugs, unless you count the use of eval EXPR. Getting
it to work under 'strict refs' would be nice, too.

=head1 AUTHOR

The Perl implementation of I<paste>
was written by Randy Yarger, I<randy.yarger@nextel.com>.

=head1 COPYRIGHT and LICENSE

This program is copyright by Randy Yarger 1999.

This program is free and open software. You may use, modify, distribute
and sell this program (and any modified variants) in any way you wish,
provided you do not restrict others to do the same.

=cut

Randy Jay Yarger        | Nextel Communications
randy.yarger@nextel.com | http://hs1.hst.msu.edu/~randy/