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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Use PERL to confirm a word is in a file.

Status
Not open for further replies.

pcutler

Technical User
Jan 18, 2002
59
CA
Hi Folks,

I’m still learning PERL and I think I’ve taken a wrong turn.

I’m working on a simple script that needs to check the contents of a file for a certain word. I’ve been playing around with the following code:

open(FNAME, 'c:\Scripts\phile.txt') or die "I can't find your file\n";
@lines = <FNAME>;
close(FNAME);

foreach $line (@lines)
{
if ($line =~ /wordX/ )
{
print "True \n" ;
}else{print "False \n" ;
}
}

exit 0

When I run the script on a four line file, the output contains three “False” and one “True”.

What I need is for the script to return “True” if it finds “wordX” any place in the file and “False” if it doesn’t.

Where did I go wrong?

Thank you for your time.

Peter.
 
Hi,

I guess what you can do is:

$string="false";

open(FNAME, 'c:\Scripts\phile.txt') or die "I can't find your file\n";

while (<FNAME>){
if(/word/){
$string = "true";
last;
}
}

close(FNAME);

print $string;
 
Code:
open(FNAME, 'c:\Scripts\phile.txt') or die "I can't find your file\n";
@lines = <FNAME>;
close(FNAME);

if ( grep /wordX/, @lines) {
	print "Found\n";
}

Now this loads the whole file into memory... fine for small files.. but septemberlogic is a lot better for large files
 
Code:
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$evil_invader[/blue] = [red]"[/red][purple]DALEK[/purple][red]"[/red][red];[/red]

[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url] INFILE, [red]"[/red][purple]enemies.txt[/purple][red]"[/red][red];[/red]
[blue]$found[/blue] = [blue]$line[/blue] =~ [red]/[/red][purple][blue]$evil_invader[/blue][/purple][red]/[/red] [olive][b]while[/b][/olive][red]([/red]![blue]$found[/blue] and [blue]$line[/blue]=<INFILE>[red])[/red][red];[/red]
[url=http://perldoc.perl.org/functions/close.html][black][b]close[/b][/black][/url] INFILE
[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple]Found[purple][b]\n[/b][/purple][/purple][red]"[/red] [olive][b]if[/b][/olive] [blue]$found[/blue][red];[/red]
Yes, I know I didn't declare $found and $line.
It's basically the same logic as septemberlogic, but on one line.
 
Well, if I wanted to check if a word is in a text file, and if it is then do one thing, and if it isn't then do another thing, I would use the code below

#! /usr/bin/perl
use strict;
use CGI ':standard';

open (LOG, "</YOUR PATH HERE/logfile.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my @logmessage = <LOG>;
close (LOG) || Error ('close', 'file');

if (@logmessage eq "true") {

print "pass"
}

else {

print "fail"
}
 
I don't think that will work, xmassey:
AFAIK,
Code:
if(@logmessage eq "true")
. . . is comparing the length of the @logmessage array against the string "true" which will never happen.
 
Well, if I wanted to check if a word is in a text file, and if it is then do one thing, and if it isn't then do another thing, I would use the code below

#! /usr/bin/perl
use strict;
use CGI ':standard';

open (LOG, "</YOUR PATH HERE/logfile.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my @logmessage = <LOG>;
close (LOG) || Error ('close', 'file');

if (@logmessage eq "true") {

print "pass"
}

else {

print "fail"
}

You should double-check your code before clicking on the submit button. There is no need to load the CGI module, there is a sub routine being called that isn't in the script: Error(), and as brigmar pointed out, you can't use "eq" to compare an array to a string.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Yeah I apologise, that script however would check if the file contains the word "true" on its own, but it wouldnt work if they file contained multiple words. My new suggestion would be to use...

$value = 4;

open (LOG, "<log.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');

while (<LOG>) {

if (/$value/) {

print "$value found".

}

close (LOG) || Error ('close', 'file');
 
I have just thought about what you said. You said that it will check the length of @logmessages and see if its the same length (is that what you meant?).

if @logmessages = hello

therefore if the code was

if (@logmessages eq "hello"){
print "hello"
}

Then surely it would see if hello is equal to hello

Or is it because of the way i've use quotes ("hello")?
 
@logmessages is an array.

The following line:
Code:
if(@logmessages eq "hello") {

is trying to perform a string comparison.
The "eq" operator is expecting both its operands to be scalars.
"hello" is a scalar
An array, when referenced in a scalar context (like here) returns the length of the array (how many elements it has).

Here's an example:
Code:
my @array=('one','two','three'); 
print "ONE" if (@array eq 'one');
print "TWO" if (@array eq 'two');
print "THREE" if (@array eq 'three');
print "Length is 3" if (@array eq '3');

 
I was presuming that 1 word was stored in the file. If I'm taking multiple words from a file then I would use split, to split all the words into individual scalers. However you would need to know how many words there are. Is there a way to count the number of words in an array, something like count(@array); ?
 
brigmar already posted the answer to your question:

An array, when referenced in a scalar context (like here) returns the length of the array (how many elements it has).

You can do this:

Code:
my $length = @array;

or, a little better since the intention is clear:

Code:
my $length = scalar @array;

but they both do the same thing: assign the length of the array to the scalar. You could have easily checked your premise above:

Code:
use warnings;

my @logmessages = ('hello');

if (@logmessages eq "hello"){
   print "hello";
}
else {
   print "no hello";
}

the output is: "no hello"

Note that there is no warning issued by perl in this circumstance. Just proves that the "warnings" pragma has a few "holes" in it because the code is clearly doing the wrong thing.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thats really strange. When I first built a user login system using perl, I used a really simple idea, which involved checking to see if the file contained the correct username and password. Below is part of my code...

$ausername = param('username');
$apassword = param('password');

$auserpass = $ausername . $apassword;

open (LOG, "<path/$ausername.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my @logincheck = <LOG>;
close (LOG) || Error ('close', 'file');

$logincheck2 = "@logincheck";

if ($logincheck2 eq $auserpass) {
open (LOG, "<path/e800k321654987.htm") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my @ebook = <LOG>;
close (LOG) || Error ('close', 'file');

print "<p><font face=arial size=2><b>Username:</b> $ausername - <b>Expires In:</b> $expire3 days</font>";
print "@ebook";
}

else {

print "no entry";



On any occassion, if the username and password picked up by the params is correct, it will print the ebook. Only if the username and password is wrong then no entry is printed...

Therefore this method has worked, so I really don't understand... If I wanted to open the file and take everything thats written and put it into a single string, what do I do, even though the method above does work for me?
 
I can only figure, that if I pass an array onto a scaler, then it counts the number of words the array contains, otherwise if I don't pass it to a scaler it prints the words contained within the array
 
Ok maybe I have figured out what you were saying...

@array = ('one', 'two', 'three');
$aaa = @array;
print "@array";

The output is the number of words the array contains (3)...

@array = ('one', 'two', 'three');
$aaa = "@array";
print "@array";

The output is the words the array contains (one two three)...
 
this line:

Code:
$logincheck2 = "@logincheck";

first makes a string of @logincheck then assigns the string value to $logincheck2.

this:

Code:
$logincheck2 = @logincheck;

assigns the length of the array to $logincheck2. The diffence behavior between the two is caused by the double-quotes. Double-quotes make strings, which is what you did to the array when you double-quoted it.

In your two code examples above, I think you meant:

Code:
@array = ('one', 'two', 'three');
$aaa = @array;
[b]print $aaa;[/b]

The output is the number of words the array contains (3)...



------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top