Home > Archive > PERL Beginners > November 2005 > Matching a Scalar Variable
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Matching a Scalar Variable
|
|
| Mazhar 2005-11-29, 3:56 am |
| Hi Folks,
I have a requirement where in i have to read a file and then store
the line by line items into a scalar variable. And then ihave ti match the
same. i am providing you a sample code. Just help how can i match a string
where in i should pass a scalar variable value.
PGM
Open (FILE1,">one Fuile");
Open (FILE,">Second File");
while (<FILE1> )
{
$line1 = $_;
while (<FILE> )
{
$line = $_;
if ($line =~ /(.*)$line1(.*)/) (Here i have to check the
value which i get from a file but it is not searching)
{
print "Got the String";
}
}
}
Please reply to me at the earliest
Regads
mazhar
| |
| Muthukumar 2005-11-29, 3:56 am |
| On 11/29/05, Mazhar <syedmazhar.hasan@gmail.com> wrote:
>
> Hi Folks,
> I have a requirement where in i have to read a file and then
> store
> the line by line items into a scalar variable. And then ihave ti match the
> same. i am providing you a sample code. Just help how can i match a string
> where in i should pass a scalar variable value.
>
> PGM
>
> Open (FILE1,">one Fuile");
> Open (FILE,">Second File");
>
> while (<FILE1> )
> {
> $line1 = $_;
> while (<FILE> )
> {
> $line = $_;
> if ($line =~ /(.*)$line1(.*)/) (Here i have to check the
> value which i get from a file but it is not searching)
> {
> print "Got the String";
> }
> }
> }
>
>
> Open (FILE1,">one Fuile");
Open (FILE,">Second File");
Change this to,
Open (FILE1,"<one Fuile");
Open (FILE,"<Second File");
> means write mode.
| |
| Mazhar 2005-11-29, 3:56 am |
| Sorry i am passing the OPEN as
Open (FILE1,"<one Fuile");
Open (FILE,"<Second File");
Still the string is ot matching. Help me please
Regards
Mazhar
On 11/29/05, Muthukumar <zenmuthu@gmail.com> wrote:
>
>
>
> On 11/29/05, Mazhar <syedmazhar.hasan@gmail.com> wrote:
> Open (FILE,">Second File");
>
> Change this to,
>
> Open (FILE1,"<one Fuile");
> Open (FILE,"<Second File");
>
>
>
>
| |
| Thomas Bätzler 2005-11-29, 3:56 am |
| Hi,
Mazhar <syedmazhar.hasan@gmail.com> asked:
> Open (FILE1,">one Fuile");
> Open (FILE,">Second File");
Please post working examples, not pseudo code.
> while (<FILE1> )
> {
> $line1 = $_;
This is bad. I'd suggest you use meaningful variable
names. They help people to understand what you're
trying to code:
while( my $pattern = <FILE1> ){
chomp( $pattern ); # remove trailing EOL
> while (<FILE> )
> {
> $line = $_;
while( my $line = <FILE> ){
> if ($line =~ /(.*)$line1(.*)/)
print "matched '$pattern' on line $." if $line =~ m/(.*?)$pattern(.*)/;
}
Also, you need (.*?) and (.*) only if you're interested in
the part of the matched line that goes before and after the
pattern. Otherwise, just say m/$pattern/.
HTH,
Thomas
| |
| xicheng 2005-11-29, 3:56 am |
| Hi Mozhar:
The problem for you is in the inside while loop, the File Handle (FILE)
goes to the end of the file, and will not return to the beginning of
the FILE unless you close/reopen it, or use s to reset it.
Good luck,
XC
Mazhar wrote:
> Hi Folks,
> I have a requirement where in i have to read a file and then store
> the line by line items into a scalar variable. And then ihave ti match the
> same. i am providing you a sample code. Just help how can i match a string
> where in i should pass a scalar variable value.
>
> PGM
>
> Open (FILE1,">one Fuile");
> Open (FILE,">Second File");
>
> while (<FILE1> )
> {
> $line1 = $_;
> while (<FILE> )
> {
> $line = $_;
> if ($line =~ /(.*)$line1(.*)/) (Here i have to check the
> value which i get from a file but it is not searching)
> {
> print "Got the String";
> }
> }
> }
>
> Please reply to me at the earliest
>
> Regads
> mazhar
| |
| Muthukumar 2005-11-29, 3:56 am |
| On 11/29/05, Mazhar <syedmazhar.hasan@gmail.com> wrote:
>
> Sorry i am passing the OPEN as
> Open (FILE1,"<one Fuile");
> Open (FILE,"<Second File");
>
> Still the string is ot matching. Help me please
Use like this:
open FD, "< file1";
open FD1, "< file2";
while (<FD> )
{
$line1=chomp($_); # chomp() Needed
while (<FD1> )
{
$line = chomp($_); # chomp() Needed
if ($line =~ /.*$line1.*/) # (.*)Not needed
{
print "Got the String\n";
}
}
}
Revert on having more queries.
| |
| Mazhar 2005-11-29, 3:56 am |
| Thank You Every Body for the Help i am able to check the same.
regards
mazhar
On 11/29/05, Muthukumar <zenmuthu@gmail.com> wrote:
>
>
>
> On 11/29/05, Mazhar <syedmazhar.hasan@gmail.com> wrote:
>
>
>
> Use like this:
>
>
> open FD, "< file1";
> open FD1, "< file2";
>
> while (<FD> )
> {
> $line1=chomp($_); # chomp() Needed
>
> while (<FD1> )
> {
> $line = chomp($_); # chomp() Needed
> if ($line =~ /.*$line1.*/) # (.*)Not needed
> {
> print "Got the String\n";
> }
>
> }
> }
> Revert on having more queries.
>
>
| |
| Mazhar 2005-11-29, 3:56 am |
| Ok Muthu,
See there is a file called as pixconfig.txt which has the entries
such as
*PIX-4-106023*
*PIX-4-101123*
*....so on*
and there is one more file called ip.log which has the entries below,
Nov 29 10:03:24 10.20.1.2 Nov 29 2005 10:33:53: %*PIX-4-106023*: Deny tcp
src inside:Blackberry/3657 dst outside:102.112.149.73/445 by access-group
"inside"
i have to macth the bold characters written in the file so i use the below
code which is not working
Open (FILE1,">pixconfig.txt");
Open (FILE,">ip.log");
while (<FILE1> )
{
$line1 = $_; (Here i Get the *PIX-4-106023* entry from the file)
while (<FILE> )
{
$line = $_;
if ($line =~ /(.*)$line1(.*)/) (Here i have to check the
value which i get from a file but it is not searching)
{
print "Got the String";
}
}
}
Please Help me out
regards
Mazhar
On 11/29/05, Muthukumar <zenmuthu@gmail.com> wrote:
>
> Can you post your exact work around on this to help you! Post script and
> files and your requirement.
>
> Regards,
> -Muthu
>
>
> On 11/29/05, Mazhar <syedmazhar.hasan@gmail.com> wrote:
>
>
>
>
| |
| Charles K. Clarkson 2005-11-29, 3:56 am |
| Muthukumar <mailto:zenmuthu@gmail.com> wrote:
No, I don't think so.
Let's test it. We'll assume that <FD> has 3 lines in it.
On the first pass of the outer loop we load the first value
from "file1." We then compare it to each value in "file2."
Fine so far.
On the second pass of the outer loop we load the second
value from "file1." But FD1 is at the end of the file, so
there is nothing to compare the second value to.
On the third pass of the outer loop we load the third
value from "file1." But FD1 is at the end of the file, so
there is nothing to compare the third value to.
This algorithm is fundamentally flawed.
: while (<FD> )
: {
: $line1=chomp($_); # chomp() Needed
:
: while (<FD1> )
: {
: $line = chomp($_); # chomp() Needed
: if ($line =~ /.*$line1.*/) # (.*)Not needed
: {
: print "Got the String\n";
: }
:
: }
: }
: Revert on having more queries.
| |
| Muthukumar 2005-11-29, 7:56 am |
| On 11/29/05, Charles K. Clarkson <cclarkson@htcomp.net> wrote:
>
> Muthukumar <mailto:zenmuthu@gmail.com> wrote:
>
>
> No, I don't think so.
>
> Let's test it. We'll assume that <FD> has 3 lines in it.
> On the first pass of the outer loop we load the first value
> from "file1." We then compare it to each value in "file2."
> Fine so far.
>
> On the second pass of the outer loop we load the second
> value from "file1." But FD1 is at the end of the file, so
> there is nothing to compare the second value to.
>
> On the third pass of the outer loop we load the third
> value from "file1." But FD1 is at the end of the file, so
> there is nothing to compare the third value to.
>
> This algorithm is fundamentally flawed.
>
>
>
> You are correct. Thanks for notifying the error(s).
May be it will work:
open FD, "< pixconfig.txt";
open FD1, "< ip.log";
@arr=<FD>;
while (<FD1> )
{
foreach $var (@arr)
{
$var=~chomp($var);
# print "Check" . $var . "<==>". $_;
if ( $_ =~ /.*$var.*/ )
{
print $_;
}
}
}
# END
when,
pixconfig.txt is containing only one word for pattern matching.
--
--
Mail: zenmuthu@gmail.com | www: http://geocities.com/kmuthu_gct/
| |
| Charles K. Clarkson 2005-11-29, 7:56 am |
| Muthukumar <mailto:zenmuthu@gmail.com> wrote:
: May be it will work:
:
:
: open FD, "< pixconfig.txt";
: open FD1, "< ip.log";
:
: @arr=<FD>;
We need to know more about file size and memory to make this
determination. Assuming you are correct about the file and memory
size, your algorithm looks fine. You just need to learn more perl
to make it work.
I think better to keep files open for the shortest time
possible, especially if this script might have several instances
running at once. It is a good practice to check I/O operations for
success.
my $file = 'pixconfig.txt';
open my $fh, '<', $file or die qq(Cannot open "$file": $!);
chomp( my @pix = <$fh );
close $fh or die qq(Cannot close "$file": $!);
You can read more about chomp in the perlfunc file or by using
perldoc from a command line (DOS box).
perldoc -f chomp
Since I introduced lexical variables above let me set you
straight about all these symbol table polluting variables you are
throwing around. *Don't use them*. Start even the smallest scripts
you write with these lines.
use strict;
use warnings;
For details:
perldoc strict
perldoc warnings
So far we have this.
#!/usr/bin/perl
use strict;
use warnings;
my $file = 'pixconfig.txt';
open my $fh, '<', $file or die qq(Cannot open "$file": $!);
chomp( my @pix = <$fh> );
close $fh or die qq(Cannot close "$file": $!);
: while (<FD1> )
: {
: foreach $var (@arr)
: {
: $var=~chomp($var);
: # print "Check" . $var . "<==>". $_;
: if ( $_ =~ /.*$var.*/ )
: {
: print $_;
: }
: }
: }
$file = 'ip.log';
open $fh, '<', $file or die qq(Cannot open "$file": $!);
while ( my $ip = <$fh> ) {
foreach my $pic ( @pix ) {
next unless $ip =~ /\Q$pic\E/;
print $ip;
}
}
close $fh or die qq(Cannot close "$file": $!);
__END__
While this is not the most optimal solution, it is easy to
read and to maintain. If ip.log is very long, another, more
advanced, solution is needed, but it would also require a more
intimate knowledge of the data.
HTH,
Charles K. Clarkson
--
Mobile Homes Specialist
254 968-8328
| |
| Charles K. Clarkson 2005-11-29, 7:56 am |
| Charles K. Clarkson <mailto:cclarkson@htcomp.net> wrote:
:
: chomp( my @pix = <$fh );
Darn!
chomp( my @pix = <$fh> );
Move along now. :)
| |
| JupiterHost.Net 2005-11-29, 6:57 pm |
|
Muthukumar wrote:
> On 11/29/05, Mazhar <syedmazhar.hasan@gmail.com> wrote:
>
>
>
>
>
> Use like this:
No, like this:
use strict;
use warnings;
Always do that, especially when posting code to this list.
> open FD, "< file1";
> open FD1, "< file2";
Is it even open?
open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
> while (<FD> )
> {
> $line1=chomp($_); # chomp() Needed
No no no, $Line1 is now a number:
perldoc -f chomp
"It returns the total number of characters removed from all its
arguments."
> while (<FD1> )
> {
> $line = chomp($_); # chomp() Needed
again, nope...
> if ($line =~ /.*$line1.*/) # (.*)Not needed
> {
> print "Got the String\n";
> }
>
> }
> }
> Revert on having more queries.
This will open both files and check each line of file2 against each line
of file1 (and it alerts you to any problems, is easier to read, best
pratice safe (hopefully ;p), ect etc):
#!/usr/bin/perl
use strict;
use warnings;
open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
while(<$file1_fh) {
my $line = $_;
chomp $line;
while(<$file2_fh> ) {
my $match_against = $_;
chomp $match_against;
print "Got the string\n" if $line =~ m{$match_against}xms;
}
}
close $file1_fh;
close $file2_fh;
| |
| Dr.Ruud 2005-11-29, 6:57 pm |
| Muthukumar:
Always put these lines on top:
use strict;
use warnings;
> $var=~chomp($var);
perldoc -f chomp
--
Affijn, Ruud
"Gewoon is een tijger."
| |
| JupiterHost.Net 2005-11-29, 6:57 pm |
|
> This will open both files and check each line of file2 against each line
> of file1 (and it alerts you to any problems, is easier to read, best
> pratice safe (hopefully ;p), ect etc):
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
> open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
>
> while(<$file1_fh) {
He he, whups :) make that
while(<$file1_fh> ) {
> my $line = $_;
> chomp $line;
>
> while(<$file2_fh> ) {
> my $match_against = $_;
> chomp $match_against;
>
> print "Got the string\n" if $line =~ m{$match_against}xms;
> }
> }
>
> close $file1_fh;
> close $file2_fh;
>
| |
| Charles K. Clarkson 2005-11-29, 6:57 pm |
| JupiterHost.Net <mailto:mlists@jupiterhost.net> wrote:
: This will open both files and check each line of file2 against
: each line of file1 (and it alerts you to any problems, is easier
: to read, best pratice safe (hopefully ;p), ect etc):
Sorry, but it won't. It will open both files and check the
first line of file1 against all the lines of file2. All the rest
of the lines in file1 are not tested. The inner loop only runs
once. The pointer into file2 is never set back to the file start.
We can test it with this. If each file has four lines in it,
we should see this result.
1234
1234
1234
1234
my $i;
while(<$file1_fh> ) {
while(<$file2_fh> ) {
print ++$i;
}
print "\n";
}
: #!/usr/bin/perl
:
: use strict;
: use warnings;
:
: open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
: open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
:
: while(<$file1_fh> ) {
: my $line = $_;
: chomp $line;
:
: while(<$file2_fh> ) {
: my $match_against = $_;
: chomp $match_against;
:
: print "Got the string\n" if $line =~ m{$match_against}xms;
: }
: }
:
: close $file1_fh;
: close $file2_fh;
HTH,
Charles K. Clarkson
--
Mobile Homes Specialist
254 968-8328
| |
| JupiterHost.Net 2005-11-29, 6:57 pm |
|
Charles K. Clarkson wrote:
> JupiterHost.Net <mailto:mlists@jupiterhost.net> wrote:
>
> : This will open both files and check each line of file2 against
> : each line of file1 (and it alerts you to any problems, is easier
> : to read, best pratice safe (hopefully ;p), ect etc):
>
> Sorry, but it won't. It will open both files and check the
> first line of file1 against all the lines of file2. All the rest
> of the lines in file1 are not tested. The inner loop only runs
> once. The pointer into file2 is never set back to the file start.
Good point :)
Perhaps I should have worded it "this does the same thgin you were doing
in your example" :)
If file1 has:
1
2
3
4
and file2 has:
a
b
c
d
then the output of:
#!/usr/bin/perl
use strict;
use warnings;
open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
while(<$file1_fh> ) {
my $line = $_;
chomp $line;
print "File 1 $line\n";
while(<$file2_fh> ) {
my $match_against = $_;
chomp $match_against;
print "\tFile 2 $match_against\n";
# print "Got the string\n" if $line =~ m{$match_against}xms;
}
}
close $file1_fh;
close $file2_fh;
is:
File 1 1
File 2 a
File 2 b
File 2 c
File 2 d
File 1 2
File 1 3
File 1 4
But if you do it liek so:
#!/usr/bin/perl
use strict;
use warnings;
open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
my @match_list = <$file2_fh>;
close $file2_fh;
while(<$file1_fh> ) {
my $line = $_;
chomp $line;
print "File 1 $line\n";
for my $match_against (@match_list) {
chomp $match_against;
print "\tFile 2 $match_against\n";
# print "Got the string\n" if $line =~ m{$match_against}xms;
}
}
close $file1_fh;
then the output is:
File 1 1
File 2 a
File 2 b
File 2 c
File 2 d
File 1 2
File 2 a
File 2 b
File 2 c
File 2 d
File 1 3
File 2 a
File 2 b
File 2 c
File 2 d
File 1 4
File 2 a
File 2 b
File 2 c
File 2 d
Thanks for catching my misstatement :)
So this will do what I originally said (IE instead of copying the
original example I commented on):
#!/usr/bin/perl
use strict;
use warnings;
open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
my @match_list = <$file2_fh>;
close $file2_fh;
while(<$file1_fh> ) {
my $line = $_;
chomp $line;
for my $match_against (@match_list) {
chomp $match_against;
print "Got the string\n" if $line =~ m{$match_against}xms;
}
}
close $file1_fh;
| |
| Charles K. Clarkson 2005-11-29, 6:57 pm |
| JupiterHost.Net <mailto:mlists@jupiterhost.net> wrote:
: Thanks for catching my misstatement :)
Thanks for finally making one. :)
: #!/usr/bin/perl
:
: use strict;
: use warnings;
:
: open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
:
: open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
: my @match_list = <$file2_fh>;
: close $file2_fh;
:
: while(<$file1_fh> ) {
: my $line = $_;
: chomp $line;
:
: for my $match_against (@match_list) {
: chomp $match_against;
: print "Got the string\n" if $line =~ m{$match_against}xms;
: }
: }
:
: close $file1_fh;
Yes, this is the option the OP chose in a message up thread
from here.
The only thing I would change is the repeated chomping of
the matches. On second thought I'll also complain about that
5-space initial indent. :)
open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
chomp( my @match_list = <$file2_fh> );
close $file2_fh;
| |
| JupiterHost.Net 2005-11-30, 3:56 am |
|
Charles K. Clarkson wrote:
> JupiterHost.Net <mailto:mlists@jupiterhost.net> wrote:
>
> : Thanks for catching my misstatement :)
>
> Thanks for finally making one. :)
No I make mistakes all the time, no doubt :)
> : #!/usr/bin/perl
> :
> : use strict;
> : use warnings;
> :
> : open my $file1_fh, '<', 'file1' or die "file1 open failed: $!";
> :
> : open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
> : my @match_list = <$file2_fh>;
> : close $file2_fh;
> :
> : while(<$file1_fh> ) {
> : my $line = $_;
> : chomp $line;
> :
> : for my $match_against (@match_list) {
> : chomp $match_against;
> : print "Got the string\n" if $line =~ m{$match_against}xms;
> : }
> : }
> :
> : close $file1_fh;
>
> Yes, this is the option the OP chose in a message up thread
> from here.
Gotcha, thats what I get basing my code off theirs without reading the
intention :)
> The only thing I would change is the repeated chomping of
> the matches.
Tur I do liek the chomp() once you did below, shame on me for not doing
that :)
> On second thought I'll also complain about that
> 5-space initial indent. :)
That had to be the mail clients, I'm a strict 4 spacer :)
> open my $file2_fh, '<', 'file2' or die "file2 open failed: $!";
> chomp( my @match_list = <$file2_fh> );
> close $file2_fh;
>
> .
> .
> .
>
> for my $match_against (@match_list) {
> print "Got the string\n" if $line =~ m{$match_against}xms;
> }
>
> Why the {}xms options on the regex? We aren't messing with $/,
> so there shouldn't be any multi-line problems. Is it just a
> precaution or is their some other reason?
>
> Christmas*, perhaps? :)
Heheh, no just habit from the "Perl Best Practices" book. (*Excelletn*
book by Damian Conway)
|
|
|
|
|