1824988 Members
1882 Online
109678 Solutions
New Discussion юеВ

search pattern issue

 
SOLVED
Go to solution
Hakki Aydin Ucar
Honored Contributor

search pattern issue

The following code clause does not find what it was supposed to be; pattern returns everything in file /tmp/UserLogin. What am I missing , any advice ?

@users=`cat /etc/passwd|awk -F: '{print \$1}'`;
my $K;
for ( $K = 1; $K <= @users; $K++ )
{
open(IN,"/tmp/UserLogin");
open(OUT,">>/tmp/LogonOutput");
while ($line=) {
$pattern = "$users[$K-1]" ;
if ( $line =~ m{$pattern} ) {
print "$pattern equal to $line\n";
print OUT "$line\n";
}
}
}


Besides,
I tried m/\b$pattern/ also ,but it did not work at all.
26 REPLIES 26
Horia Chirculescu
Honored Contributor

Re: search pattern issue

Hello,

Why m/ ? (Multiple lines?) you only read one line at at a time, so should use s/

Best regards
Horia.
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

Seems that default is single line... Sorry.
Best regards from Romania,
Horia.
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

Horia,

m/ stand for match , but seems useless somehow here, I tried without m like this:
if ( $line =~ /\b$line/ )

it worked now.

thanks
Horia Chirculescu
Honored Contributor

Re: search pattern issue

Ohhh.. One mistake:

Move

open(IN,"/tmp/UserLogin");
open(OUT,">>/tmp/LogonOutput");

outside for ! You actually read the same data a lot of times...

Horai

Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

And... When done, you should close the files

close(IN)
close(OUT)

Best regards,
Horia.
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

$line =~ /\b$line/ and it worked?!

Meaning $line was searched for $line?
Best regards from Romania,
Horia.
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

>Horia:$line =~ /\b$line/ and it worked?!

Meaning $line was searched for $line?

Right, it is mistake, I just noticed that put OPEN File handler out of for loop, but I am still unable to pick from file what I wanted.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

Try

($line =~ m/$pattern{0}/ )

Horia.
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

@users=`cat /etc/passwd|awk -F: '{print \$1}'`;
my $K;
#open(IN,"/tmp/UserLogin");
open(OUT,">>/tmp/LogonOutput");

for ( $K = 1; $K <= @users; $K++ )
{
open(IN,"/tmp/UserLogin");

while ($line=)
{
$pattern = "$users[$K-1]" ;

if ( $line =~ m/$pattern{0}/ ) {
print "$pattern equal to $line\n";
print OUT "$line\n";
}
}

close(IN);

}
Best regards from Romania,
Horia.
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

>Horia: ($line =~ m/$pattern{0}/ )

only the first pattern working, others not working, problem is why perl picks up all pattern they are not even on the $pattern values ?

Regards,
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

Sorry for points assigned in reverse posts but all belongs to you eventually.
Thanks, the problem solved apparently now, but another problem ,if patterns don t match , still written into OUTPUT file ??

is it weird ? something is missing in the loop ?
Horia Chirculescu
Honored Contributor

Re: search pattern issue

There should be nothing in the output file if nothing to match...

What exactly do you get in the output file in this case?

Horia.
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

.. and do not forget to close (OUT) when exit for (not pasted in my example code)
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

#!/usr/bin/perl
@users=`cat /etc/passwd|awk -F: '{print \$1}'`;
my $K;
open(OUT,">>/tmp/LogonOutput");

for ( $K = 1; $K <= @users; $K++ )
{
open(IN,"/tmp/UserLogin");
while ($line=)
{
$pattern = "$users[$K-1]" ;


if ( $line =~ m/$pattern{0}/ ) {
print "$pattern equal to $line\n";
print OUT "$line\n";
}
}
close(IN);

}

close(OUT);
Best regards from Romania,
Horia.
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

>Horia:There should be nothing in the output file if nothing to match...
What exactly do you get in the output file in this case?

this is from output file:
LOGIN Sep 17 2010 18:03:09
root Sep 17 2010 18:03:24
student Sep 20 2010 13:55:45


LOGIN and root are not in the @users list but goes to output file ??
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

Horia,

I tried to change environment and seems its working now , so my test server has some problems by Perl sources ??
I will notify the solution after completed tests.
Thanks
Hakki
Horia Chirculescu
Honored Contributor
Solution

Re: search pattern issue

I believe user "root" should be in /etc/passwd so will be present also in @users list.

This could be true also for the "student" user.

Looks strange the presence of LOGIN.

grep LOGIN /etc/passwd?


Can you attach the file /tmp/UserLogin ?

Horia.
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: search pattern issue

>I tried to change environment

What exactly did you changed in the env. ?

Horia.
Best regards from Romania,
Horia.
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

>Horia:I believe user "root" should be in /etc/passwd so will be present also in @users list.

No, I took it out from passwd file with "grep -v"

I meant another server with environment change.

Last script is here (working great now!)
@users=`cat /etc/passwd|awk -F: '{print \$1}'|grep -vE 'root|nwauto|daemon|bin|sys|adm|uucp|lp|www|webadmi
n|hpdb|informix|nuucp|smbnull|mysql|nwcron|goglobal|alop|trop|dbadmin|c7op|sysadmin`;
my $K;
open(OUT,">>/tmp/LogonOutput");
for ( $K = 1; $K <= @users; $K++ )
{
open(IN,"/tmp/UserLogin");
while ($line=)
{
$pattern = "$users[$K-1]" ;
if ( $line =~ m/\b$pattern{0}/ ) {
print "$pattern equal to $line\n";
print OUT "$line";
}
}
close(IN);
}
close(OUT);
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

>Horial: if ( $line =~ m/$pattern{0}/ )

what exactly means that {0} in $pattern{0} ?
Horia Chirculescu
Honored Contributor

Re: search pattern issue

Read about quantifiers in (and search google for more):

http://www.perlmonks.org/?node_id=967

Best regards,
Horia.
Best regards from Romania,
Horia.
James R. Ferguson
Acclaimed Contributor

Re: search pattern issue

Hi Hakki:

There are a number of things wrong in your script.

First, you count starting an an index of one. Perl is zero relative. Your 'for' loop thus skips the first entry in the '/etc/passwd' file and attempts to process a non-existent one when it compares '$K<='.

Contrast your code to this:

#!/usr/bin/perl
use strict;
use warnings;
my ( @users, $K );
@users=`cat /etc/passwd|awk -F: '{print \$1}'`;
for ( $K = 0; $K < @users; $K++ ) {
print $users[$K];
}

...

Next, the above is horribly un-Perlish. You start a external process to fill an array and then immediately fork a 'cat' and an 'awk' when the 'awk' would do alone (if this were a shell program). There is *no* need for any of this in a Perl script.

Instead do something like:

#!/usr/bin/perl
use strict;
use warnings;
my $fh;
my $file = '/etc/passwd';
my @users;
open( $fh, '<', $file ) or die "Can't open '$file': $!\n";
while (<$fh>) {
push @users, (split /:/) [0];
}
for my $user (@users) {
print "$user\n";
}

I would urge you to use the three-argument form of 'open()' too.

Regards!

...JRF...
Hakki Aydin Ucar
Honored Contributor

Re: search pattern issue

>JRF:

Great and very Perlish solution :) Thanks.
What method do you recommend to get rid of unwanted system users like grep -v is for All lines but those matching are printed ?

All lines but those matching are printed.

@users=`cat /etc/passwd|awk -F: '{print \$1}'|grep -vE 'root|nwauto|daemon|bin|sys|adm|uucp|lp|www|we
badmin|hpdb|informix|nuucp|smbnull|mysql|nwcron|goglobal|alop|trop|dbadmin|c7op|sysadmin|ftp`;

Best Regards,
Hakki
James R. Ferguson
Acclaimed Contributor

Re: search pattern issue

Hi (again) Hakki:

> What method do you recommend to get rid of unwanted system users

One way is to create a hash of exclusions. Then, skip the processing of any user that exists in the hash:

# cat ./dousers
#!/usr/bin/perl
use strict;
use warnings;
my $fh;
my $file = '/etc/passwd';
my @users;
my %exclude;
@exclude{qw( root daemon bin sys adm uucp lp nuucp hpdb nobody www)} = ();
open( $fh, '<', $file ) or die "Can't open '$file': $!\n";
while (<$fh>) {
push @users, ( split /:/ )[0];
}
for my $user (@users) {
print "$user\n" unless exists $exclude{$user};
}
1;

Regards!

...JRF...