Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Reconcile one list against another

by wind (Priest)
on May 04, 2011 at 18:41 UTC ( [id://902966]=note: print w/replies, xml ) Need Help??


in reply to Reconcile one list against another

Just use grep:
foreach my $line (@file1) { if (my @matched = grep {$line =~ /\Q$_\E/i} @users) { print "YES @matched is on $line \n"; } else { print "nope...\n"; } }

Replies are listed 'Best First'.
Re^2: Reconcile one list against another
by jpl (Monk) on May 04, 2011 at 18:53 UTC
    This will do what the OP said he wanted to do, but should user ed match a line for user ted or fred. The OP will probably be better off isolating (just) the user names from both files, then doing exact matching.

      That is true, my code was just meant to solve is state variable quandary.

      Without thinking too deeply about it, your noted problem might be solved by simply adding some word boundaries:

      if (my @matched = grep {$line =~ /\b\Q$_\E\b/i} @users) {
Re^2: Reconcile one list against another
by spartan (Pilgrim) on May 04, 2011 at 19:52 UTC
    Far out wind... That is exactly the problem I was trying to solve...

    How to iterate over the entire list in a (seemingly) atomic operation to see if a list of users could have possibly matched my list of accounts.

    I kept thinking a loop in a loop, and that was obviously wrong.

    Very funny Scotty... Now PLEASE beam down my PANTS!

Re^2: Reconcile one list against another
by spartan (Pilgrim) on May 04, 2011 at 20:23 UTC
    Ok, so you can show what users have accounts, unfortunately I'm trying to show the exact opposite. Here is what I came up with:

    #!/usr/bin/perl use strict; use Data::Dumper; # Grep a user OUT of a file, given a list of names, likely from anothe +r file # psuedo code: # if file1 contains a name from file2, skip the line # if file1 does NOT contain a name from file2, print the line. # # I am using this to determine a list of accounts on the partners serv +er # that, *maybe*, shouldn't be on there any more. my @users; my %lines; my $file1=$ARGV[0]; my $file2=$ARGV[1]; open FILE1, "<$file1" or die "Cannot open $file1: $!\n"; # Hasherize it!!! foreach my $line (<FILE1>) { chomp($line); $lines{$line}=0; } close FILE1; # Create @users array open FILE2, "<$file2" or die "Cannot open $file2: $!\n"; foreach my $line (<FILE2>) { if ($line =~ /#/) { my @out=split /\s+/,$line; push @users,$out[1]; } } close FILE2; foreach my $key (keys(%lines)) { foreach my $user (@users) { if ($key =~ /$user/i) { $lines{$key}++; } } } print "List of users not authorized to have an account\n"; foreach my $key (sort keys(%lines)) { if ($lines{$key} <= 0) { print "$key\n"; } } print "\nList of users authorized to have an account\n"; foreach my $key (sort keys(%lines)) { if ($lines{$key} > 0) { print "$key\n"; } }

    It handily prints out what should be there, and what should not. Now all I have to do is some manual verification, and I can call this a lesson learned.

    Many thanks to all those with quick replies, and mostly to jpl for the hint in the direction of hashes.

    wind: You code is excellent, but only prints out those folks authorized to have accounts, how would I modify your code to print the inverse list? I tried negating the match (=~ to !=~), but it failed in a quite spectacular way.

    UPDATE:
    I added a sort into each foreach loop above to print out the lines in alphabetical order.

    Very funny Scotty... Now PLEASE beam down my PANTS!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://902966]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (2)
As of 2024-06-22 04:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.