Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Convert Windows batch file into Perl script

Status
Not open for further replies.
Aug 22, 2002
113
FR
Hello,


I would like to convert the following Windows batch file into a Perl script:

1. set logs_dir=E:\Program Files\nsr\logs
2. set savegrp_tmp="%logs_dir%\savegrp_tmp.log"
3. nsrlog -f %savegrp_tmp%
4. for /F "tokens=8 delims==, " %%a in ('findstr level %savegrp_tmp%') do set level=%%a
5. if %level% EQU skip goto end
6. for /F "tokens=2-4 delims=/ " %%a in ('date /t') do set date=%%b-%%a-%%c
7. for /F "tokens=1-2 delims=: " %%a in ('time /t') do set time=%%a_%%b
8. for /F "tokens=8" %%a in ('findstr Savegroup %savegrp_tmp%') do set group=%%a
9. set group_dir="%logs_dir%\savegroups\%group%"
10. set report=%group_dir%\report_%date%_%time%.log
11. copy %savegrp_tmp% %report%
12. :end
13. type %savegrp_tmp% >> "%logs_dir%\savegrp.log"
14. del %savegrp_tmp%

Here’s a description of what each line of the script does:

1. set the variable logs_dir
2. set the variable savegrp_tmp
3. create a text file with the file name and path as defined in the previous variables
4. search for the word next to “level” and store it in a variable
5. if that word equals “skip”, end the script.
6. store the date in a variable
7. store the time in a variable
8. search for the word next to “Savegroup” and store it in a variable
9. set the variable group_dir
10. set the variable report
11. copy the text file into another location
12. continue from here condition in line 5 is true
13. append the text file to another file
14. delete the file

I would like to add a feature to the script which apparently isn’t possible using batch files. Before the 11th line I want to check if the destination directory exists and if it does not, I want it to be created.

Thanks for all your help.
 
I just thought of this which should work if you want to keep this as a windows batch script.
It's been a while, so I'm not sure if it's foolproof, but it seems to work.

cd %logs_dir%
if %ERRORLEVEL%==0 (
echo %logs_dir% exists
) else (
md %logs_dir%
)
cd
If you want to rewrite it in perl it would be a good exercise.. you could probably do it in a couple days with a decent book.

-jt
 
Even though batch language has no explicit test for whether a directory exists, you can take advantage of the fact that every directory always contains at least directory entries (. and ..)

Try this comamnd before line 11:

IF NOT EXISTS %GROUP_DIR%\. THEN MKDIR %GROUP_DIR%
 
I was just playing around with your method sampsonr, and it seems that if a file exists with the same name as the directory you're checking for, it returns true which is kind of strange.
Even if you try to create a directory that already exists, its contents won't be clobbered anyway, but if a *file* exists, you end up appending the contents of the file you're trying to copy, and the existing file.
 
Thanks for your help but I'm really looking into rewriting this script in Perl as I will be using it in both Unix and Windows.

Any tips/suggestions are welcome.

Thanks again.
 
Here is a rough translation. I have had no way to test it because I have no input data or idea of what you are trying to accomplish. I have labeled each line in the script to correspond to the functions in your .bat file. I was unclear of some of the things and noted the areas that need more explanation.

1. $logs_dir = "e:/program files/nsr/logs";
2. $savegrp_tmp = "$logs_dir/savegrp_tmp.log"
3. need more explanation (what is nsrlog -f)?
4. need more explanation (search for what from where)?
5. if ($level eq "skip") {
13. open (IN, "$savegrp_tmp") || die $!;
13. open (OUT, ">>$logs_dir/savegrp.log") || die $!;
13. while (<IN>) {
13. print OUT;
13. }
13. close (IN);
13. close (OUT);
14. unlink ($savegrp_tmp);
exit; #kills the script
}
6. and 7. ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
8. need more explanation (search for what from where)?
9. $group_dir = &quot;$logs_dir/savegroups/$group&quot;;
10. $report = &quot;$group_dir/report_$year$mon$mday.log&quot;;
11. open (IN, &quot;$savegrp_tmp&quot;);
11. open (OUT, &quot;>$report&quot;);
11. while (<IN>) {
11. print OUT;
11. }
11. close (IN);
11. close (OUT);
?? does the stuff after :end get run when the script does not find &quot;skip&quot;?

If you can explain the unclear items to me, I will fill in the rest of the script and then help you troubleshoot it if it does not work right away.
 
Hello raklet, thanks for your code. Here are the answers to your questions:

3. The “nsrlog” is a Legato NetWorker program that outputs a log text file. I suppose we would use something along the lines of “system('nsrlog -f $savegrp_tmp'); ?
4. Search for the word that is right to the word level in the text file $savegrp_tmp and set it to a variable. Here's an example of a line that contains the word:
myserver: /nsr level=full, 9608 KB 00:01:00 544 files8.
8. Get the 4th word of the first line of the $savegrp_tmp file. Here's an example :
NetWorker Savegroup: (notice) SERVER completed, 1 client(s) (All Succeeded)
In this case the word is “SERVER”.

The stuff after :end must always be run.

Thanks again.
 
Here is the rest of the script. Let me know how it works - there will probably be bugs as it is untested.

$logs_dir = &quot;e:/program files/nsr/logs&quot;;
$savegrp_tmp = &quot;$logs_dir/savegrp_tmp.log&quot;
system(&quot;nsrlog -f $savegrp_tmp&quot;);
open (IN, &quot;$savegrp_tmp&quot;);
while (<IN>) {
($level) =~ /level=(.+?)\s/i;
if ($level eq &quot;skip&quot;) {
close (IN);
&cleanup;
}
}
close (IN);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
open (IN, &quot;$savegrp_tmp&quot;);
while (<IN>) {
split(/\s+/);
$group = $_[3];
last;
}
$group_dir = &quot;$logs_dir/savegroups/$group&quot;;
$report = &quot;$group_dir/report_$year$mon$mday.log&quot;;
open (IN, &quot;$savegrp_tmp&quot;);
open (OUT, &quot;>$report&quot;);
while (<IN>) {
print OUT;
}
close (IN);
close (OUT);
&cleanup;


sub cleanup {
open (IN, &quot;$savegrp_tmp&quot;) || die $!;
open (OUT, &quot;>>$logs_dir/savegrp.log&quot;) || die $!;
while (<IN>) {
print OUT;
}
close (IN);
close (OUT);
unlink ($savegrp_tmp);
exit;
}
 
Your code seems perfect but I’m having trouble with the « nsrlog » program that should output a text file but it doesn’t. This program doesn’t generate any data by itself but instead it takes the data from standard input or from an existing file to then format it and write it to the file specified by the –f switch.

If I try this: system (&quot;nsrlog -f $savegrp_tmp < $savegrp_test&quot;);

It works perfectly. So apparently the problem is that it does not read from standard input.

But I’ve also tried something like this:

open (FH, &quot;>$outfile&quot;) || die &quot;Cannot open $input for writing\n&quot;;

while (<STDIN>) {
print FH;
}
close (FH);

if (-z $outfile) {
die &quot;No input\n&quot;;
}


The result is: “No input”;

Why isn’t the script reading from standard input? I don’t have this problem with the batch file which outputs data correctly to the log file.

Thanks for your help.
 
You want to capture the result of nsrlog -f and place it into $savegrp_tmp?

In that case, you have to capture the result of nsrlog -f (which is being sent to <STDOUT>) into a variable and then write the variable into the file. The way you redirect <STDOUT> to a variable is by using backticks ` `. Note that it is a backtick - ` and not a comma - '.

open (OUT, &quot;>$savegrp_tmp&quot;);
$results = `nsrlog -f`;
print OUT $results;




 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top