mgolini has asked for the wisdom of the Perl Monks concerning the following question:

Brothers - I seek your guideance. I am developing (on a novice level mind you) a script to: 1. Look at files(csv) in a directory 2. Check for version. 3. Copy version "24" directly to an output directory. 4. Prepend two lines to version "17" and copy it to the same directory as version 24. 5. Change all the file names (all files are now v24) to read "something_Events_date" I can get up to step 4 with no big problems, but Step 5 is giving me fits. I split on an underscore and save it in an array. But renaming the file a second time does not work well. If someone can point out what I am doing incorrectly, I would appreciate it.
#! perl.exe -w # Perl Script to change format of .csv files from version 17 to versio +n 24. # This script will add two lines to the beginning of each file #and copy the file to a final directory destination. use File::Copy; $indir = "c:/public/conversion"; $outdir = "c:/public/final"; opendir DH,$indir or die "Cannot open $indir: $!"; ## has all the files and directories in the given ## directory. You'll want to screen it to make sure you're ## opening a file. foreach $file(readdir DH) { $name = $file; next if $name =~ /^\./; # skip over dot files &addheader($_); } close DH; # &changename($_); sub addheader { open FH, "< $indir/$file" or printf "can't open %s\n",$file; $line = <FH>; $_ = $line; close FH; $field1 = m/^Clock/; # Check for Clock at beginning of file printf "\n$file"; if ( $field1 == "1"){ printf "\tv17\tFile Needs Appending\n"; open FH1, "< $indir/$file" or printf "can't open %s\n", $file; + # Open source file open FH2, '> c:/public/final/tmp.csv' or die "can't append: $! +" ; # Open target file - create if not there already print FH2 "PREPEND LINE1\n"; # Prepend text print FH2 "PREPEND LINE2\n"; my @lines = <FH1>; foreach $line ( @lines ) { print FH2 $line; } close FH1; close FH2; #$file = $correct; $oldfile = 'c:/public/final/tmp.csv'; $newfile = "$outdir/$file"; rename $oldfile,$newfile or die"can't rename files\n"; } else { printf "\tv24\tFile Does Not Need Appending\n"; copy "$indir/$file", "$outdir/$file"; } print "\n"; @test = split /_/, $file; $correct ="$test[0]"."\_Events_2003080\n"; $oldfile = 'c:/public/final/$file'; $newfile = "$outdir/$correct"; copy $oldfile, $newfile or die "Can't rename file second time\ +n"; return ; }

Replies are listed 'Best First'.
Re: File prepend , copy, & rename
by chromatic (Archbishop) on Aug 25, 2003 at 22:24 UTC
    foreach $file(readdir DH) { $name = $file; next if $name =~ /^\./; # skip over dot files &addheader($_); }

    Style issues: there's no need to copy $file to $name. There's also no need to use the ampersand when calling functions. It'd be a bug if you were passing $_ to addheader() when you really mean $file, but you're lucky (in a dubious sense) to be using globals.

    sub addheader { open FH, "< $indir/$file" or printf "can't open %s\n",$file; $line = <FH>; $_ = $line;

    You're ignoring the passed-in variable. You're attempting to read from a file if it doesn't open (where you should be dieing or at least not continuing). You're assigning to $_ unnecessarily.

    $field1 = m/^Clock/; # Check for Clock at beginning of file printf "\n$file"; if ( $field1 == "1"){

    You're performing an assignment, not a regex match. Use =~ instead. (That one trips me up occasionally too.) You also probably don't want to do a numeric comparison against a string. Either use eq, or drop the quotes around 1. Also, $field1 comes from nowhere. It only appears in a previous line, and it definitely will never contain what you think it should sometimes contain.

    my @lines = <FH1>; foreach $line ( @lines ) { print FH2 $line; }

    File::Copy will do this for you much better, with much less code.

    $oldfile = 'c:/public/final/$file';

    $file won't interpolate in single quotes.

    That should get you started. If you fix your variable passing, you'll be a lot further; then you can add strict and warnings to have perl catch many of these for you.

      TNX for the help, it works now and much smoother than I expected. ;-)