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

Hi, Im new to Perl and am trying to write a script to execute .bat files every 2 seconds. Im able to do it, as long as the file name is file1.bat, file2.bat, file3.bat etc where 1, 2, 3 etc are the variables. This works fine, but when I try to make the name "file" also a variable, I get an error "unknown file", apparently because when I try to concat the first string (in this case either "file" or "text" or "xyz") with the 2nd string (which is a number). The end result needs to be either file1.bat, file2.bat.... or xyz1.bat, xyz2.bat etc. where the character part of file name remains a constant but the number changes. Could anybody help pls. Here is the script
print "Enter the number in the first batch file:\n"; $f=<STDIN>; print "Enter the number in the last batch file:\n"; $l=<STDIN>; for ($i=$f;$i<=$l; $i++) { $t="file"; $concatfile=$t and $i; $file="$concatfile.bat"; system($file); sleep(2); }

20050504 Janitored by Corion: Added formatting

20050505 Edit by Corion: Changed title from 'Perl help'

20050505 Edit by Corion: Changed title from 'PERL help'

Replies are listed 'Best First'.
Re: concatenating strings
by gellyfish (Monsignor) on May 04, 2005 at 11:16 UTC

    You are not doing what you think you are doing with $concatfile=$t and $i; I would suggest that you print out the contents of $file instead of the system($file) so you can see what is going on.

    /J\

Re: concatenating strings
by tlm (Prior) on May 04, 2005 at 11:23 UTC

    To concatenate, do this

    $concatfile = "$t$i";
    or this
    $concatfile = $t . $i;
    ...though in this case you might as well do the whole thing in one swoop, and check return status while you're at it:
    system( "$t$i.bat" ) == 0 or die "system( $t$i.bat ) failed: $?";
    You may need to use $^E instead of $? for that error check (though I'm not familiar enough with Win32 programming to know for sure).

    the lowliest monk

      I did that, but I get an error, "unknown file". However, if I specify the value of $t = xyz and then $concatfile = $t.$i, it works perfectly. The moment I enter the value of $t, it gives an error. Is there some kind of format to concat 2 strings, one of which is a variable entered during file execution, <STDIN>?

      Tried the ^ too, is this what you mean?

      print "Enter the common character in the batch file:\n"; $t=<STDIN>; print "Enter the number in the first batch file:\n"; $f=<STDIN>; print "Enter the number in the last batch file:\n"; $l=<STDIN>; for ($i=$f;$i<=$l; $i++) { #$t="file"; #$concatfile=$t.$i; #$file="$concatfile.bat"; system( "$^t$i.bat" ); #system($file); sleep(2); }

      Janitored by Arunbear - added code tags, as per Monastery guidelines

        tlm's code is correct, so if there's anything not working, I suspect you're not removing the newline from the filename (a line from a filehandle will always end in newline unless EOF happens first)

        you should do something like:

        print "Enter basename: "; my $filename = <STDIN>; chomp $filename;

        You can check that the variables actually contain what you think they do by printing them out with delimiters around them:

        print "File=>>$filename<<\n";
        imperl, I suspect you did not read this, which suggests you to print out the filename you're building: print is your friend in debugging! Moreover, use strict and use warnings should never miss when building example codes to post here: they will answer many questions much more quickly than us! As a final note, you should use <code> tags when posting :)

        I think that you have problems with the newline: when you read from STDIN, it will be put inside $f. Just chomp inputs:

        print "Enter the common character in the batch file:\n"; chomp(my $f = <STDIN>); print "Enter the number in the last batch file:\n"; chomp(my $l=<STDIN>); # Now both $f and $l have no trailing newline

        Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

        Don't fool yourself.

        You probably need to chomp the line-termination sequence off that user input. Try

        $t = <STDIN>; chomp $t; # removes trailing line-termination sequence # ... system( "$t$i.bat" ) == 0 or die "system( $t$i.bat ) failed: $^E";

        the lowliest monk

Re: concatenating strings
by sh1tn (Priest) on May 04, 2005 at 11:45 UTC
    Just make cleaner style and maybe you'll see you error:
    my $file_name = 'file'; print "Enter the number in the first batch file:\n"; $f=<STDIN>; print "Enter the number in the last batch file:\n"; $l=<STDIN>; for( $f..$l ){ my $file="$file_name$_.bat"; system($file) == 0 or die $?; sleep(2); }


Re: concatenating strings
by Animator (Hermit) on May 04, 2005 at 11:19 UTC

    In addtion to gellyfish's advice: enable warnings aswell, it will (or should) give a warning...

    And, for the record, it is Perl or perl, but never PERL (can someone consider this thread and suggest a title-change?)

      oops, sorry bout that, I did actually try $concat=$t.$i. And will remember Perl and not PERL :)
Re: concatenating strings
by cog (Parson) on May 04, 2005 at 15:36 UTC
    Also, testing whether the file exists and is executable might not be a bad idea. You can do that with the -x switch:

    unless (-x $file) { warn "file $file does not appear to exist or is not executable\n"; next; }

    That will also tell you the name of the file not found. Put it right before the system call.

Re: concatenating strings
by aditya.singh (Acolyte) on Jun 24, 2005 at 09:05 UTC
    1. Do a chomp after you read from STDIN.
    2. To concatenate you use '.'. Eg. $concatfile=$t . $i;
    3. Move the $t="file"; out of the loop, if you aren't changing it in the loop.
    4. use strict; use warnings; and use my.
    5. Instead os system, do a print "$file\n";. See the command you are issuing. You could try specifying the full path to the .bat file.
    6. Use the perl debugger. perl -d scriptname