LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   perl grep function (https://www.linuxquestions.org/questions/linux-newbie-8/perl-grep-function-884455/)

casperdaghost 06-04-2011 12:09 AM

perl grep function
 
FILE
short@shortcasper-laptop:more Daccount.t | tail -5

USERID ACCOUNTNUM
badam4 w7897C Dru100 dmu107g
bfdam4 w90581 Dru1720 dmu118f
bhdam5 w90781C Dru120 dmu118f
bsdam7 w65665 Dru90 dmu118d
bwdams w665C Dru90 dmu118d

short@casper-laptop: more Duser.txt | tail -5
FILE2
USERID CLIENTID
badam4 f#OI[S[) 0 0 0 0 0 -1.000 -1.000 -1.000 -1 450640
bfdam4 J|T;[y& 0 0 0 0 0 -1.000 -1.000 -1.000 -1 246267
bhdam5 l+X7Kp$+ 0 0 0 0 0 -1.000 -1.000 -1.000 -1 363076
bsdam7 x([=KNW$ 0 0 0 0 0 -1.000 -1.000 -1.000 -1 476250
bwdams w".t-R 0 0 0 0 0 -1.000 -1.000 -1.000 -1 21528

So i have the two files above - file and file2. notice how the USERID is the same in the two files. what i have to do is get the USERID out of FILE1 and the grep the userid out of FILE2 to get the matching CLIENTID.

ultimately i need to print out the USERID , ACCOUNTNUM and CLIENTID in one line. But for now with the script below, all I get is the one CLIENTID from the FILE2. I have been working on this all night and can't figure it out. The results should be a whole list of CLIENTID's, not just one value - namely the last value. I be the answer is really simple.

1 #!/usr/bin/perl -w
2 open FILE1 , "/home/shortcasper/Daccount.txt" or die "Could not open $!";
3 open FILE2 , "/home/shortcasper/Duser.txt" or die "Could not open $!";
4 my @arry1 = <FILE1>;
5 my @arry2 = <FILE2>;
6 my $line = 0 ;
7 my $foo = 0;
8 foreach $line( @arry1) {
9 ($userid, $acct, $CCP, $creditman) = split /\s+/, $line;
10 @foo = grep(/$userid/, @arry2);
11 }
12
13
14
15 foreach $foo(@foo){
16 ($userid2, $you, $wnum, $zoo, $suc, $dig, $crag, $tip, $ger, $nin, $waw, $clientid) = split /\s+/, $foo;
17 print "$clientid\n" ;
18 sleep 1;
19 }
20

results is

21528 (the CLIENTID in that last line of FILE2 - that is it. it should be the whole list. )

grail 06-04-2011 04:44 AM

Does it have to be perl?
Code:

awk 'FNR == NR{a=$1;$1="";list[a] = $0;next}{if($1 in list)print $1,list[$1],$2}' file file2

grail 06-04-2011 04:44 AM

Please also use [code][/code] tags to help make code more readable.

casperdaghost 06-04-2011 05:02 AM

Since the second foreach loop only acts on the last line of the FILE2 i think that i need to nest the second foreach loop better so it iterates over each line of FILE2

Code:

#!/usr/bin/perl -w
 open FILE1 , "/home/shortcasper/Daccount.txt" or die "Could not open $!";
 open FILE2 , "/home/shortcasper/Duser.txt" or die "Could not open $!";
 my @arry1 = <FILE1>;
 my @arry2 = <FILE2>;
 my $line = 0 ;
 my $foo = 0;
 foreach $line( @arry1) {
    ($userid, $acct, $CCP, $creditman) = split /\s+/, $line;
    @foo = grep(/$userid/, @arry2);
      }

 foreach $foo(@foo){
 ($userid2, $you, $wnum, $zoo, $suc, $dig, $crag, $tip, $ger, $nin, $waw, $clientid) = split /\s+/, $foo;
 print "$clientid\n" ;
 sleep 1;
 }


grail 06-04-2011 06:39 AM

Had a play ... this seems to work:
Code:

#!/usr/bin/perl

open FILE1 , "f1" or die "Could not open $!";
open FILE2 , "f2" or die "Could not open $!";

my @arry1 = <FILE1>;
my @arry2 = <FILE2>;

foreach $line( @arry1) {
        next if $line =~ /USERID/;
        ($userid, $acct, $CCP, $creditman) = split /\s+/, $line;
        @foo = grep(/$userid/, @arry2);
        ($userid2, $you, $wnum, $zoo, $suc, $dig, $crag, $tip, $ger, $nin, $waw, $clientid) = split /\s+/, $foo[-1];
        print "$clientid\n" ;
        sleep 1;
}


casperdaghost 06-04-2011 08:10 AM

nice... yeah it works.

it also works when i add foreach loop after the grep
Code:

@foo = grep(/$userid/, @arry2);
        foreach $foo(@foo){
        ($userid2, $you, $wnum, $zoo, $suc, $dig, $crag, $tip, $ger, $nin, $waw, $clientid) = split /\s+/, $foo[-1];
        print "$userid, $acct, $clientid\n" ;
        }

Even when i tag on a print "$userid, $acct, $clientid\n"; - it still works -
it grabs all the values from both arrays perfectly.

what is the foo[-1] do? the script will run without it. yet i am hesitant to take it off.

grail 06-04-2011 09:10 AM

It doesn't work for me because as you can see my code does not loop through the @foo array like yours does, but unless there is a chance you will return more than one line
the foreach is not required. The foo[-1] returns the last element in the array. Could have easily been a 0 if only one item is returned.

chrism01 06-04-2011 08:46 PM

In general can I suggest you change the start to
Code:

#!/usr/bin/perl -w
use strict;

and do a
Code:

perl -wc file.pl
and deal with any errors/warnings before running a perl prog.
Also, using scalars and arrays (or hashes) with the same name (eg 'foo') makes the code hard to read & can easily lead to obscure errors.


All times are GMT -5. The time now is 01:53 PM.