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

hi monks, can any one help me actually i am having some set of directories like batch1, batch2 etc and in each directory they is some number of text files like file1.txt, file2.txt etc.
#!/usr/bin/perl print "Content-type:text/html\n\n"; $parval="stat1_val"; if($parval eq "stat1_val"){ print "<b>Statistics of RUNS</b>"; my $var ; my $buffer=$ENV{'QUERY_STRING'}; my($path1,$filename)=split('#',$buffer); print "$path1 and $filename\n"; print "<html><head><body><form name=frm1>"; for my $path ( grep -d, </var/www/directory/*> ) { my($first,$second,$third,$directory,$batches)=split('/' +,$path); my($ss,$ss1)=split('batch',$path); print "<div id=$ss1 name=file><li><a href=?$path#$var o +nClick='oncli();'>$ss1 $batches</a></li></div>"; } my @var=`ls -f $path1| grep '.txt\$'`; foreach $var(@var){ $var=~s/\s+//g; print qq{<div id=siva><li><a href=# onclick="javascript +:window.open('readfile.pl?$path1/$var','To Read theText File','width=500,height=600')"> $i $var</a></li></div>}; } print "</form></body></html>"; } my program output is like this 1 batch1 2 batch2 3 batch3 4 batch4 5 batch5 file2.txt file5.txt file1.txt file3.txt but i need it in the following format 1 batch1 file2.txt file5.txt file1.txt file3.txt 2 batch2 3 batch3 4 batch4 5 batch5
Thanks in advance

Replies are listed 'Best First'.
Re: how to format perl/cgi output in web page
by ww (Archbishop) on Nov 03, 2008 at 13:55 UTC

    This is a bit hard to follow:

    The output shown does not match the output of your script: Among others:

    • Run from the command line, the script's output (renamed to .htm or .html) produces links using javascript, not plain text.
    • Your "<b>Statistics of RUNS</b> and" is printed before the "<html><head><body><form name=frm1>" and thus will not appear in a browser
    • You show a form which should have its "name" quoted - eg name="frm1" and no action=(some executable).
    • ....

    Line 4, if($parval eq "stat1_val"){, is always true... so why are you using the conditional?

    The .html is not valid. All the occurances of <li>...</li> should be inside an <ol>...</ol> or <ul>...</ul>

    The occurances of <div id=$ss1 name=file></div> are invalid when between </li> and the next <li>.

    You've given us no clues about the content of the javascript and left us guessing about the content of readfile.pl

    Please clarify.

Re: how to format perl/cgi output in web page
by ig (Vicar) on Nov 03, 2008 at 17:16 UTC

    The two loops in your program (the first producing the list of batches and the second producing the list of files) do not appear to have much to do with each other. Assuming that both loops are actually looking at the same directories (i.e. that $path1 begins with /var/www/directories), then you might find something like the following works:

    #!/usr/bin/perl use strict; use warnings; print "Content-type:text/html\n\n"; my $parval="stat1_val"; if($parval eq "stat1_val"){ print "<b>Statistics of RUNS</b>"; my $var ; my $buffer=$ENV{'QUERY_STRING'}; my($path1,$filename)=split('#',$buffer); print "$path1 and $filename\n"; print "<html><head><body><form name=frm1>"; for my $path ( grep -d, </var/www/directory/*> ) { my($first,$second,$third,$directory,$batches)=split('/' +,$path); my($ss,$ss1)=split('batch',$path); print "<div id=$ss1 name=file><li><a href=?$path#$var o +nClick='oncli();'>$ss1 $batches</a></li></div>"; if($path eq $path1) { my @var=`ls -f $path1| grep '.txt\$'`; my $i = 0; foreach $var(@var){ $var=~s/\s+//g; print qq{<div id=siva><li><a href=# onc +lick="javascript:window.open('readfile.pl?$path1/$var','To Read theTe +xt File','width=500,height=600')"> $i++ $var</a></li></d +iv>}; } } } print "</form></body></html>"; }

    I have added use strict; and use warnings;. You should make a habit of using these in your programs.

    I added declaration and initialization of $i, and incremented it each time through the loop.

    I moved the loop which iterates over the text files inside the loop which iterates over the directories, assuming the two loops were dealing with the same directories. If this assumption is wrong, what I have done will not work for you. You may have to change the condition on the if statement, depending on what your input looks like.

    You should learn how to write secure CGI programs. There are some good pointers in Resources for learning CGI programming and CGI-perl resources?.

    You might be interested to learn about glob. Your use of backticks spawns a separate process, which may be a performance issue, and it introduces security risks which can be avoided using glob. I would have done something more like the following:

    foreach my $path (glob("/var/www/directory/*")) { next unless(-d $path); # produce output for each directory if($path eq $path1) { foreach my $file (glob("$path/*.txt")) { # produce output for each file } } }

    You should learn how to write secure CGI programs. One good resource is http://oreilly.com/catalog/cgi2/chapter/ch08.html and you will find pointers to other information in the links above.

      hi ig, Thank you for your answer. I would like to know about perl/cgi so could please tell me weather their is any book for perl/cgi. Thanks in advance