#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2

    Perl cannot read input text file created by a batch file


    Perl cannot read input text file created by a batch script. I am using the diamond operator. <>

    I know I am doing it correctly because if I create the input text file manually, it works. But if I create one by echoing the words into a file using a batch script, Perl cannot read it for some reason.

    Why is this?
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2005
    Posts
    22
    Rep Power
    0
    No there shouldn't be any problem reading a text file created by any script. Just to trial i tried this on my machine to be certain.

    perl Code:
     
    $ echo "hello" > test.txt
    $ perl -e 'open( FD,"<test.txt" ); my @t=<FD>; print @t;'
    hello
    $


    Post you both your batch and your perl script here. A text file is no different from being created either by batch or any other script. Is there a file before you use perl to read it. Have you checked the error code returned by the open? Is there anything inside the file which was cerated by batch? Can you see the file?

    ssharish2005
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    The batch file that is created and the file that I created are the same. Lets call this file input.txt. But the batch file created one cannot be found by the perl script. Notice I'm inputing variables with the batch script. All this works fine as the output is the same either way, but something the perl script cant see if its created via batch.


    Here is part of the batch:

    Code:
    @echo off
    
    
    echo s >> "input.txt"
    echo !var5b! >> "input.txt"
    echo !var5a! >> "input.txt"
    echo !var2a! >> "input.txt"
    echo !var2b! >> "input.txt"
    echo !var3a! >> "input.txt"
    echo !var3b! >> "input.txt"
    echo y >> "input.txt"
    
    cd "E:\Program Files (x86)\Ubisoft\SilentHunterIII\Dynamic Campaign\Perl"
    
    perl PosTimeFilter.pl input.txt
    
    pause


    Here is the perl script

    Code:
    #!/usr/local/bin/perl -w
    #
    # Script for removing units outside a specified area and time from the 
    # *.mis files of SH3.
    # Written by LGN1, March 2010
    #
    
    use strict;
    # SCR, RND, or LND layer
    print "SCR, RND, or LND? (s/r/l)";
    my $dlayer = <>;
    chomp($dlayer);
    my $layer = " ";
    if ($dlayer eq "r") {$layer = "RND"}
    else {$layer = "LND"};
    if ($dlayer eq "s") {$layer = "SCR"};
    open(READF,"Campaign_$layer.mis")
        or die "Error while opening the file: $!\n";
    
    print "Start date (YYYYMMDD) (default 19390101): ";
    my $startdate = <>;
    if ($startdate eq "\n") {$startdate = 19390101;print "Default: $startdate\n"}
    else {chomp ($startdate)};
    print "End date (YYYYMMDD) (default 19451231): ";
    my $enddate = <>;
    if ($enddate eq "\n") {$enddate = 19451231;print "Default: $enddate\n"}
    else {chomp ($enddate)};
    print "Upper longitude[km] (default: 5000): ";
    my $upperlong = <>;
    if ($upperlong eq "\n") {$upperlong = 5000;print "Default: $upperlong\n"}
    else {chomp($upperlong)};
    print "Lower longitude[km] (default: -8000): ";
    my $lowerlong = <>;
    if ($lowerlong eq "\n") {$lowerlong = -8000;print "Default: $lowerlong\n"}
    else {chomp($lowerlong)};
    print "Upper latitude[km] (default: 10000): ";
    my $upperlat = <>;
    if ($upperlat eq "\n") {$upperlat = 10000;print "Default: $upperlat\n"}
    else {chomp($upperlat)};
    print "Lower latitude[km] (default: 0): ";
    my $lowerlat = <>;
    if ($lowerlat eq "\n") {$lowerlat = 0;print "Default: $lowerlat\n"}
    else {chomp($lowerlat)};
    # change from km to meter
    $upperlong = $upperlong * 1000;
    $lowerlong = $lowerlong * 1000;
    $upperlat = $upperlat * 1000;
    $lowerlat = $lowerlat * 1000;
    print "Checking...\n";
    
    # Initialize some variables
    my $deleteunit = 1;
    my $timeframe = 1;
    my $redstring = " ";
    my $counter = 0;
    my $groupcount = 0;
    my $unitcount = 0;
    my $unitcounter = 1;
    my $prevunitcount = 0;
    my $section = "[Group ";
    if ($layer eq "RND") {$section = "[RndGroup "};
    my $nextunit = $section.$unitcounter."]";
    my $prevunit = " ";
    my $stringlength = length($nextunit);
    my @delindx = ();
    my @delgroupindx = ();
    my @delunitindx = ();
    my $unitswitch = "n";
    my $ordswitch = "n";
    my $LongInside = 0;
    my $LatInside = 0;
    my $groupsfound = 0;
    my $unitsfound = 0;
    # Read file and check lines
    while((defined(my $i = <READF>))) {
        $redstring = substr($i,0,$stringlength);
        if ($redstring eq $nextunit) {
    	if (($deleteunit == 0) && ($timeframe == 1)){
    #	    print "$prevunit inside! \n \n";
    	    $counter++}
    	else {push(@delindx,$prevunitcount)};
    #	print "Found $nextunit \n";
    	$prevunitcount = $unitcounter;
    	$unitcounter++;
    	$deleteunit = 1;
    	$timeframe = 1;
    	$prevunit = $nextunit;
    	$nextunit = $section.$unitcounter."]";
    	$stringlength = length($nextunit);
        };
        $redstring = substr($i,0,14);
        if ($redstring eq "GameEntryDate=") {
    	$redstring = substr($i,14);
    	if ($redstring > $enddate) {$timeframe = 0};
        };
        $redstring = substr($i,0,13);
        if ($redstring eq "GameExitDate=") {
    	$redstring = substr($i,13);
    	if ($redstring < $startdate) {$timeframe = 0};
        };
        $redstring = substr($i,0,5);
        if ($redstring eq "Long=") { #print "Longitude found!\n";
    	$redstring = substr($i,5);
    	if (($redstring < $upperlong) && ($redstring > $lowerlong)) {
    	    $LongInside = 1;
    	};
        };
        $redstring = substr($i,0,4);
        if ($redstring eq "Lat=") { #print "Latitude found!\n";
    	$redstring = substr($i,4);
    	if (($redstring < $upperlat) && ($redstring > $lowerlat)) {
    	    $LatInside = 1;
    	};
            if (($LongInside == 1) && ($LatInside == 1)) {
    #	    print "Waypoint inside!\n";
    	    $deleteunit = 0;
    	};
    #        else {print "Waypoint outside!\n" };
            $LongInside = 0;
            $LatInside = 0;
        };
        $redstring = substr($i,0,8);
        if ($redstring eq "[Unit 1]") {
    	if (($deleteunit == 0) && ($timeframe == 1)){
    #	    print "$prevunit inside! \n";
    	    $counter++}
    	else {push(@delindx,$prevunitcount)};
    	$unitswitch = "y";
    	@delgroupindx = @delindx;
    	$groupcount = $counter;
    	$groupsfound = $unitcounter - 1;
    	$counter = 0;
    	@delindx = ();
    #	print "Found [Unit 1]\n";
    	$deleteunit = 1;
    	$timeframe = 1;
    	$prevunitcount = 1;
    	$unitcounter = 2;
    	$prevunit = "[Unit 1]";
    	$nextunit = "[Unit 2]";
    	$section = "[Unit ";
    	$stringlength = length($nextunit);
        };
        $redstring = substr($i,0,16);
        if ($redstring eq "[OrdnanceUnit 1]") {
    	if (($deleteunit == 0) && ($timeframe == 1)){
    #	    print "$prevunit inside! \n";
    	    $counter++}
    	else {push(@delindx,$prevunitcount)};
    	if ($unitswitch eq "n") {
    	    @delgroupindx = @delindx;
    	    @delunitindx = ();
    	    $groupcount = $counter;
    	    $groupsfound = $unitcounter - 1;
    	} else {@delunitindx = @delindx;
    		$unitcount = $counter;
    		$unitsfound = $unitcounter - 1;
    		$counter = 0};
    	@delindx = ();
    #	print "Found [OrdnanceUnit 1]\n";
    	$ordswitch = "y";
    	$deleteunit = 1;
    	$timeframe = 1;
    	$prevunitcount = 1;
    	$unitcounter = 2;
    	$prevunit = "[OrdnanceUnit 1]";
    	$nextunit = "[OrdnanceUnit 2]";
    	$section = "[OrdnanceUnit ";
    	$stringlength = length($nextunit);
        };
    };
    if (($deleteunit == 0) && ($timeframe == 1)){
    #    print "$prevunit inside! \n";
        $counter++}
    else {push(@delindx,$prevunitcount)};
    if ($ordswitch eq "n") {
        if ($unitswitch eq "n") {
    	@delgroupindx = @delindx;
    	@delindx = ();
    	$groupcount = $counter;
    	$groupsfound = $unitcounter - 1;
    	$counter = 0;
        } else {
    	@delunitindx = @delindx;
    	@delindx = ();
    	$unitcount = $counter;
    	$unitsfound = $unitcounter - 1;
    	$counter = 0;
        };
        $unitcounter = 1;
    };
    my $dummy = shift(@delgroupindx);
    my $dummy1 = 0;
    my $dummy2 = "PosTime_Campaign_".$layer.".mis";
    my @delordindx = @delindx;
    my $delNrgroup = @delgroupindx;
    my $delNrunit = @delunitindx;
    my $delNrordn = @delordindx;
    print "Final results: \n";
    print "**************\n";
    print "$groupsfound group(s) found! \n";
    print "$groupcount group(s) inside! \n";
    print "$unitsfound unit(s) found! \n";
    print "$unitcount unit(s) inside! \n";
    $unitcounter--;
    print "$unitcounter ordnance unit(s) found! \n";
    print "$counter ordnance unit(s) inside! \n \n";
    close(READF);
    
    print "Extract units (y/n)? ";
    my $extract = <>;
    chomp($extract);
    if ($extract eq "y"){
        print "Start extracting...\n";
        open(READF,"Campaign_$layer.mis")
    	or die "Error while opening the file: $!\n";
        open(WRITEF,"> $dummy2")
    	or die "Error while opening the file: $!\n";
        my $oldcount = 1;
        my $newcount = 0;
        my $write = 1;
        my $delcounter = 0;
        $section = "[Group ";
        if ($layer eq "RND") {$section = "[RndGroup "};
        $nextunit = $section.$oldcount."]";
        $prevunit = $nextunit;
        $stringlength = length($nextunit);
        @delindx = @delgroupindx;
        my $maxindx = $delNrgroup;
        my $prevstringlength = $stringlength;
        my $modstring = "";
        my $modstring2 = "";
        while((defined(my $i = <READF>))) {
    	$redstring = substr($i,0,8);
    	if ($redstring eq "[Unit 1]") {
    	    $oldcount = 1;
    	    $newcount = 0;
    	    $section = "[Unit ";
    	    $nextunit = "[Unit 1]";
    	    $stringlength = length($nextunit);
    	    @delindx = @delunitindx;
    	    $maxindx = $delNrunit;
    	    $delcounter = 0;
    	};
    	$redstring = substr($i,0,16);
    	if ($redstring eq "[OrdnanceUnit 1]") {
    	    $oldcount = 1;
    	    $newcount = 0;
    	    $section = "[OrdnanceUnit ";
    	    $nextunit = "[OrdnanceUnit 1]";
    	    $stringlength = length($nextunit);
    	    @delindx = @delordindx;
    	    $maxindx = $delNrordn;
    	    $delcounter = 0;
    	};
    	$redstring = substr($i,0,$stringlength);
    	if ($redstring eq $nextunit) {
    	    if ($delcounter < $maxindx) {
    		if ($oldcount == $delindx[$delcounter]) {
    		    $delcounter++;
    		    $write = 0;
    		    $newcount--;
    		} else {$write = 1};
    	    } else {$write = 1};
    	    $oldcount++;
    	    $newcount++;
    	    $prevstringlength = $stringlength;
    	    $prevunit = $nextunit;
    	    $nextunit = $section.$oldcount."]";
    	    $stringlength = length($nextunit);
    	};
    	$redstring = substr($i,0,14);
    	if ($redstring eq "[EditorParams]") {$write = 1};
    	if ($write == 1) {
    	    $dummy1 = $prevstringlength - 1;
    	    $redstring = substr($i,0,$dummy1);
    	    $dummy = substr($prevunit,0,$dummy1);
    	    if ($redstring eq $dummy) {
    		$modstring = substr($i,$dummy1);
    		$modstring2 = $section.$newcount.$modstring;
    		print WRITEF $modstring2}
    	    else {print WRITEF $i};
    	};
        };
        close(READF);
        close(WRITEF);
    };
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    input.txt will look something like this:

    Code:
    s
    19400101
    19400102
    12194
    12190
    65227
    65220
    y
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    Feel free to test it out yourself. Just copy the perl code above and call it PosTimeFilter.pl, and use this batch code below, variables removed.

    Code:
    @echo off
    
    del input.txt /q
    
    echo s >> "input.txt"
    echo 19400101 >> "input.txt"
    echo 19400102 >> "input.txt"
    echo 12194 >> "input.txt"
    echo 12190 >> "input.txt"
    echo 65227 >> "input.txt"
    echo 65220 >> "input.txt"
    echo y >> "input.txt"
    
    
    cd "E:\Program Files (x86)\Ubisoft\SilentHunterIII\Dynamic Campaign\Perl"
    
    perl PosTimeFilter.pl input.txt
    
    pause

    And as a control, create a text file like so:

    Code:
    s
    19400101
    19400102
    12194
    12190
    65227
    65220
    y

    Try them both. The text file created by the batch above wont work and the bottom text file will.

    Am I getting the perl command prompt wrong?
    Code:
    perl PosTimeFilter.pl input.txt
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    when you manually create that file you must type in the lines, not copy paste from the batch created file. If you copy and paste into the file you've crfeated, it still will not work.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    836
    Rep Power
    496
    You create your file in a directory, then change directory to the perl directory and then launch Perl from there. Your input.txt file is located somewhere else and Perl cannot find it, because it is looking for it in the current directory (E:\Program Files (x86)\Ubisoft\SilentHunterIII\Dynamic Campaign\Perl), not where you created it.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    Originally Posted by Laurent_R
    You create your file in a directory, then change directory to the perl directory and then launch Perl from there. Your input.txt file is located somewhere else and Perl cannot find it, because it is looking for it in the current directory (E:\Program Files (x86)\Ubisoft\SilentHunterIII\Dynamic Campaign\Perl), not where you created it.
    The batch file, the perl script and the text input files are all in the same directory, the one you listed.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    Originally Posted by ssharish2005
    No there shouldn't be any problem reading a text file created by any script. Just to trial i tried this on my machine to be certain.

    perl Code:
     
    $ echo "hello" > test.txt
    $ perl -e 'open( FD,"<test.txt" ); my @t=<FD>; print @t;'
    hello
    $


    Post you both your batch and your perl script here. A text file is no different from being created either by batch or any other script. Is there a file before you use perl to read it. Have you checked the error code returned by the open? Is there anything inside the file which was cerated by batch? Can you see the file?

    ssharish2005
    Yes the batch script does what it is intended to do and populates input.txt with the lines I want. Problem is, if input.txt is even touched by a batch script, I cannot input it into the perl script as a replacement to the STDIN, <>

    Not sure what the issue is here. Can anyone reproduce this?

    If I can't figure this out I'll have to convert the perl script into batch and place it within my batch file. That could be a pain in the a$$
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    54
    Rep Power
    2
    Solved:

    Apparenty I put spaces at the end of each line. The perl script input fields didn't like this. That threw me off because it was saying it could not read or find the file.

    This is the fix in the batch script:


    Code:
    echo s>> "input.txt"
    echo 19400101>> "input.txt"
    echo 19400102>> "input.txt"
    echo 12194>> "input.txt"
    echo 12190>> "input.txt"
    echo 65227>> "input.txt"
    echo 65220>> "input.txt"
    echo y>> "input.txt"

IMN logo majestic logo threadwatch logo seochat tools logo