in reply to IO::Handles ... any good?

You should use strict and warnings in your script. They help you in writing better code.

You can use the predefined array @ARGV. It contains all arguments given to the script.

With ./script.pl file1.txt file2.txt you should find the two file names inside @ARGV.

Then you can do your modifications foreach file...

#! /usr/bin/perl use strict; use warnings; FILE: for my $file ( @ARGV ) { # check if $file contains a file name if ( !-f $file ) { warn "Sorry, '$file' doesn't look like a file!\n"; next FILE; } # if we can't open the file for reading, warn user if ( !open(my $infh, '<', $file) ) { warn "Sorry, couldn't open $file: $!\n"; } # we could open the file for reading else { # so, let's try to open a temporary file for writing if ( !open( my $outfh, '>', $file.'.new' ) ) { # and warn user if it failed warn "Sorry, couldn't open $file.new for writing: $!\n"; } else { # we now have two filehandles: # one to read from and one to write to. # read linewise from input filehandle while ( my $line = <$infh> ) { # print (to output filehandle) original line and append a newl +ine print $outfh $line, "\n" or die "writing to $file.new failed: +$!\n"; } # writing should be done now; close filehandle close $outfh or die "closing $file.new failed: $!\n"; } # reading should be done now; close filehandle close $infh or die "closing $file failed: $!\n"; } }

code was hacked quickly and is not tested!

You can do this even in one line ;o)

perl -i.bak -pe '$_.="\n"' file1.txt file2.txt file...

this was quickly tested and worked so far ;o)

Updates:

Replies are listed 'Best First'.
Re^2: IO::Handles ... any good?
by blowupp (Novice) on Mar 22, 2009 at 20:58 UTC

    Quite a bit beyond me but... wow, I will use as a shell alias - thanks.
    Here's my effort at decoding your line :

    perl <br> -i #edit in place .bak #but make a new file -p # read every line from default arg e # excecute code from command line ' #code for the default while loop $_ # default variable, each line of file . # and = # equal to " #start printing this literally \n #new line " #finish literal printing ' # end/start next loop
      perl -i # edit in place .bak # rename original file by appending .bak to filename; print to n +ew file with original name -p # use a while loop to read each file; print each line (is stored + in $_) which you have read (and modified) e # excecute code from command line ' # start of code to be executed (for the default while loop) $_ # default variable, each line of file .= # append the following to yourself ($_) and assign it to you "\n" # string to be appended ' # end of code

      $_ .= "\n"; is the shorter form of $_ = $_ . "\n";

      Check perlrun and look for the explanation for option -i. They have some examples there. -p should be explained in more details, too.

        -p should be explained in more details, too.

        -p is nicely explained using Deparse.
        >perl -MO=Deparse -pe"body()" LINE: while (defined($_ = <ARGV>)) { body(); } continue { die "-p destination: $!\n" unless print $_; } -e syntax OK
Re^2: IO::Handles ... any good?
by gulden (Monk) on Mar 22, 2009 at 19:00 UTC
    The single command line is quite interesting. However, it's possible to run that command without changing the original file?

      Currently I only have this solution for a single file:

      perl -pe '$_.="\n"' file1.txt > file1.new

      It's untested but should read file1.txt and print the modified version into file1.new.

      I have no idea, how to perform this with multiple files in one (simple) command.

      You could still use a shell for loop to perform this upon several files...

      # bash for FILE in *.txt; do perl -pe '$_.="\n"' $FILE > $FILE.new; done

        Windows shell would be

        for %q in (*.txt) do perl -pe"$_.=$/" "%q" > "%q.new"

        And a golfed version would be

        perl -nEsay # 5.10 perl -pe$_.=$/ # <5.10 Windows perl -pe'$_.=$/' # <5.10 bash