#!/usr/bin/env perl # # $Id$ # # append - append files to other files, then remove the originals use strict; use warnings; use Getopt::Std; use File::Basename; #--- command line parsing for options --# # my %opt; getopts( 'fkh?', \%opt ); if ( $opt{'h'} || $opt{'?'} ) { print STDERR <; close($tgt_fh); if (@tgt) { # there is something to append # read the lines in the source open( my $src_fh, '<', $src ) or die("cannot read '$src': $!\n"); my @src = <$src_fh>; close($src_fh) or warn("cannot close file after reading from '$src': $!\n"); # determine the number of lines to skip # (how many initial lines in @src are equal to final lines in @tgt) my $nr_lines_to_skip = 0; for ( my $s = $#src ; $s >= 0 ; --$s ) { #warn("examining slice up to $src:$s\n"); my $still_equal = 1; my $nr_equal = 0; for ( my $t = $#tgt ; $t >= 0 && $s - $nr_equal >= 0 ; --$t ) { #warn(sprintf("comparing: %s[%s] (%s) and %s[%s] (%s)\n", $tgt, $t, $tgt[$t] =~ s#\s+$##r, $src, $s - $nr_equal, $src[ $s - $nr_equal ] =~ s#\s+$##r)); if ( $tgt[$t] eq $src[ $s - $nr_equal ] ) { ++$nr_equal; #warn("$nr_equal equal lines found\n"); } else { #warn("not equal\n"); $still_equal = 0; # we can't skip from the start last; } } if ( $still_equal && $nr_equal > 0 ) { # $src[$s .. $#src] is identical to $tgt[0 .. $nr_equal_lines - 1] $nr_lines_to_skip = $nr_equal; warn("$nr_equal lines will be skipped\n"); last; } } if ( $nr_lines_to_skip != $#src + 1 ) { # not all lines are being skipped open( my $tgt_fh, '>>', $tgt ) or die("cannot append to '$tgt': $!\n"); foreach my $s ( $nr_lines_to_skip .. $#src ) { print $tgt_fh $src[$s]; } close($tgt_fh) or warn("cannot close file after appending to '$tgt': $!\n"); } } } else { # append the whole content, no matter what it is open( my $tgt_fh, '>>', $tgt ) or die("cannot append to '$tgt'\n"); open( my $src_fh, '<', $src ) or warn("cannot open input from '$src': $!\n"); local $/ = undef; my $appendage = <$src_fh>; print $tgt_fh $appendage; close($src_fh) or warn("cannot close file after reading from '$src': $!\n"); close($tgt_fh) or warn("cannot close file after appending to '$tgt': $!\n"); } ( $src eq '-' ) or $opt{'k'} or unlink($src) or warn("cannot remove input file '$src': $!\n"); } } #--- go go go! ---# # my $target = pop(@ARGV) || '-'; if ( $opt{'f'} && $target eq '-' ) { die("cannot use option -f when appending to standard output\n"); } foreach my $arg ( @ARGV ? @ARGV : ('-') ) { append( $arg, $target ); }