Q: using perl for cgi script that pulls lines from text file 
Author Message
 Q: using perl for cgi script that pulls lines from text file

Hello Folks,

Thanks in advance for any help you can provide, and I'm sorry if this
is an extemely basic question. I've already searched for answers in the
usual places.

Problem:

I need to write a perl-cgi program that accepts post data from a form,
puts the data into a perl varible and then searches a text file to see
which lines contain the varible, and print those lines (to stdout web client)
that match.

Progress to date:

I have no problem reading in the varible from the post-form data, parsing
it out. Opening and printing out the text file to the web client. The
problem occurs when trying to match the varible against the current line
from the text file.

I use the substring 'index' function in perl against the textfile line "<F>".  
It sort of works, it pulls out SOME of the lines that match but not all!
The program seems to ignore some lines in the text file.

I'm new to perl and am unsure of the best way to read and test-match a line from
a text file.

##Below is an example of the code I use.
##$in is the input for the post-form data:

$hits = 0;
$file = "test.text";
open(F,$file) || die "Cannot open $file: $!";
while (<F>)  {
        $hits = index(<F>, /$in/ );

        if ($hits > 0) {
        print;
        print " <hr> \n";
        $hits = 0      
           }

Quote:
}

# end while <F> is open

##Below is an example of the test.text file I'm trying to search:

sen1.tacil.mass.com 138.219.484.12 gogo bbb/cgi-bin/test.date /bin/date
sen1.tacil.mass.com 138.219.484.12 gogo bbb/cgi-bin/test.date /bin/date
sen1.tacil.mass.com 138.219.484.12 gogo /cgi-bin/test.date /bin/date
sen1.tacil.mass.com 138.219.484.12 gogo bbb/cgi-bin/test.date /bin/date
sen1.tacil.mass.com 138.219.484.12 gogo /cgi-bin/test.date /bin/date
sen1.tacil.mass.com 138.219.484.12 gogo /cgi-bin/test.date /bin/date

## if $in = 'bbb', 1 lines prints back.            
## if $in = 'com', 4 lines prints back.            

Thanks again for any help you can provide.



Sat, 27 Jun 1998 03:00:00 GMT  
 Q: using perl for cgi script that pulls lines from text file
Just want to say thanks for the quick response from Hugo.
His explanation was concise and right on the money.
His code snippet below worked like a champ.
A large part to getting it to work properly is understanding
how $_ works.

Quote:
>To be honest, you don't really need that $hits variable at all that I
>can see - I'd simplify the loop to:
>  while (<F>) {
>    next if index($_, $in) < 0;
>    print $_, " <hr> \n";
>  }

>Hugo van der Sanden



Sun, 28 Jun 1998 03:00:00 GMT  
 Q: using perl for cgi script that pulls lines from text file
: Progress to date:
:
: I have no problem reading in the varible from the post-form data, parsing
: it out. Opening and printing out the text file to the web client. The
: problem occurs when trying to match the varible against the current line
: from the text file.
:
: I use the substring 'index' function in perl against the textfile line
: "<F>".
This is one of the problems: '<F>' isn't the line just read, it is a
command to read a new line from the file. Note that:
  while (<F>) {
will read a line from the file into $_ for each pass through the loop, and
it is $_ that you should be checking in your index() call.

The second problem is also with index(), since this command will search
for a fixed string, not a regexp, so what you actually want is:
  $hits = index($_, $in);

The third problem is with the return value from index(), which will be
0 if the substring matched the beginning of the line and -1 if no match
was found. (This assumes you haven't changed $[ elsewhere in the script.)
So the test needs to be:
  if ($hits >= 0) {
to avoid missing lines that match from the beginning.

To be honest, you don't really need that $hits variable at all that I
can see - I'd simplify the loop to:
  while (<F>) {
    next if index($_, $in) < 0;
    print $_, " <hr> \n";
  }

Hugo van der Sanden



Sun, 28 Jun 1998 03:00:00 GMT  
 Q: using perl for cgi script that pulls lines from text file
I think I can handle this one (maybe I'm less of a newbie than I used to
be, eh? :)

The problem is that <F> means "read in another line from file F and put it
in the $_ variable.

Quote:
>$hits = 0;
>$file = "test.text";
>open(F,$file) || die "Cannot open $file: $!";
>while (<F>)  {

This use of <F> reads in a line from F and puts it in $_.

Quote:
>        $hits = index(<F>, /$in/ );

This reads in a *second* line from F.  The first line from F is now
discarded, thus you are only actually working with every other line.

Quote:
>        if ($hits > 0) {
>        print;
>        print " <hr> \n";
>        $hits = 0;

Here's where I may be making newbie mistakes still, but I believe the best
way to do the above is:

  while(<F>) {
    print $_,"<hr>\n" if /$in/;
  }

I could get to like this stuff...

============================================================================

College Technology Systems Manager         |
Indiana University of Pennsylvania         | Web home page:
G-4 Stright Hall, IUP                      |   http://www.iup.edu/~manutter/
Indiana, PA 15705                          |
"Imitation is the sincerest form of piracy"|
----------------------------------------------------------------------------



Mon, 29 Jun 1998 03:00:00 GMT  
 Q: using perl for cgi script that pulls lines from text file
: I think I can handle this one (maybe I'm less of a newbie than I used to
: be, eh? :)

way to go, mark!

--

     President of the IUP Computer Science Club
          http://www.lib.iup.edu/~carney/



Mon, 29 Jun 1998 03:00:00 GMT  
 Q: using perl for cgi script that pulls lines from text file

Quote:

>Here's where I may be making newbie mistakes still, but I believe the best
>way to do the above is:

>  while(<F>) {
>    print $_,"<hr>\n" if /$in/;
>  }

Yes, but that's unneccessarily readable ;-)

How about:

print join('<BR>\n', grep(/$in/, <FIL>));

This works too, although it's a bit more opaque. Let's dissect
it and see how.

This line is implicitly a loop -- mediated by grep(). grep is
a really cool toy and I'm sorry it's so woefully underused ...

grep(expression,list) iterates over all the items in <list>,
and applies <expression> to them. It returns an array of all
items for which <expression> evaluated to true.

In this case, grep(/$in/, <FIL>), we are iterating over a
file handle; in effect, we scan through all the lines that can
be read from FIL. The expression we're applying is a pattern
match, /$in/, i.e. match lines containing $in. So grep()
finds all the lines containing $in in FIL.

Now we want to print this list of matches, but there's a
problem; it's an array. So we can turn it into a single scalar
by using join(), to join all the elements together (using
"<BR>\n" as a separator).

Finally, we print all this.

It helps to be able to read backwards, doesn't it?

Quote:
>I could get to like this stuff...

You'n'me both. Perl is better than most controlled substances.

--



Mon, 06 Jul 1998 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. pull out last line in a text file

2. running perl at command line with arguments: script.cgi?text=text

3. running perl at command line with arguments: script.cgi?text=text

4. reading lines from one file and pulling matching lines in another

5. Pulling comments out of gif files using Perl

6. Want to delete a line from a file using a PERL script

7. pulling an attached file with perl script in .forward

8. REQ: SIMPLE CGI TO SEARCH A TEXT FILE AND RETURN ANY LINES CONTAINING KEYWORD

9. script that will exclude lines with shebang from text file

10. Help with pulling text out of a Tk::Text

11. How do I read line by line of data from a file using perl

12. Qs for professional Perl/CGI developers

 

 
Powered by phpBB® Forum Software