#!/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; use File::Basename qw(basename); use Getopt::Std qw(getopts); use constant EX_SUCCESS => 0; use constant EX_FAILURE => 1; my $Program = basename($0); my ($VERSION) = '1.4'; my (@fh, @sep, %opt); getopts('d:s', \%opt) or usage(); @ARGV or usage(); if (defined $opt{'d'}) { @sep = split //, eval { "$opt{d}" }; } else { @sep = ("\t"); } foreach my $f (@ARGV) { if ($f eq '-') { push @fh, *STDIN; } else { if (-d $f) { warn "$Program: '$f': is a directory\n"; exit EX_FAILURE; } my $fil; unless (open $fil, '<', $f) { warn "$Program: '$f': $!\n"; exit EX_FAILURE; } push @fh, $fil; } } if ($opt{'s'}) { for my $i (0..$#fh) { my $fh = $fh[$i]; my $current_sep = 0; my $tline; while(<$fh>) { chomp; $tline .= $_ . $sep[$current_sep]; $current_sep = ($current_sep + 1) % scalar(@sep); } chop $tline; print "$tline\n"; close $fh; } exit EX_SUCCESS; } while (files_open()) { my $current_sep = 0; my $tline; for my $i (0..$#fh) { if (not eof $fh[$i]) { my $fh = $fh[$i]; my $line = <$fh>; chomp($line); $tline .= $line; } if ($i != $#fh) { $tline .= $sep[$current_sep]; $current_sep = ($current_sep + 1) % scalar(@sep); } } print "$tline\n"; } exit EX_SUCCESS; sub files_open { for my $f (@fh) { return 1 unless eof $f; } return 0; } sub usage { print "usage: $Program [-s] [-d list] file ...\n"; exit EX_FAILURE; } sub VERSION_MESSAGE { print "$Program version $VERSION\n"; exit EX_SUCCESS; } __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 separated by a tab character (or by the characters listed in the -d option). The argument '-' will result in standard input being read. If '-' is repeated, standard input will be read one line at a time for each instance of '-'. =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. =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/