chaoticbear has asked for the wisdom of the Perl Monks concerning the following question:

I'm fairly new to Perl and I can't quite figure out what I want to do from the Llama. My situation: I'm polling a router for a list of output, and dumping that into @int_descriptions. That part's fine. I also have a text file, foo.txt with a bunch of lines of stuff. I need to figure out a way to grep that file and return any term of my array that (case-insensitive) matches any line of that text file. On this scale, efficiency isn't terribly important; I'll have at maximum around 2k lines in the array, and about 50 in the text file. I'm thinking I could also do:
open FILE,"$filename" or die $!; my @other_array = <FILE>;
I've found enough documentation online to be able to grep a single term/regex and spit it out from an array, but I can't figure out how I can do an any to any mapping.

Replies are listed 'Best First'.
Re: Grep lines from a text file, compare to an array using regex?
by choroba (Cardinal) on Jun 08, 2014 at 21:04 UTC
    You can convert it to a problem you already know how to solve by just creating one large regular expression from all the lines you want to search for.
    my $pattern = join '|', map quotemeta, @lines; $pattern = qr/^(?:$pattern)$/;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Grep lines from a text file, compare to an array using regex?
by AnomalousMonk (Archbishop) on Jun 08, 2014 at 21:47 UTC
Re: Grep lines from a text file, compare to an array using regex?
by LanX (Saint) on Jun 08, 2014 at 21:25 UTC
    if you want to grep on whole fields, you might be able to use a hash.

    Just be sure to always lowercase the keys to be case insensitive.

    kind of:

    $hash{lc($key)}=$line; # for file to search print @hash{@to_find}; # @to_find from grep-file

    If possible I'd prefer this over the hassle to avoid regex-metacharacters.

    YMMV! =)

    Cheers Rolf

    (addicted to the Perl Programming Language)

Re: Grep lines from a text file, compare to an array using regex?
by ww (Archbishop) on Jun 08, 2014 at 21:42 UTC

    Or ( ... without grep, either OS-native nor Perl ...and definitely not to deprecate either suggestion above... ) you could go with a pair of arrays, this way:

    #!/usr/bin/perl -w use 5.016; use strict; # 1089209.pl my @int_descriptions; # OP suggests the seeker knows how to + obtain the array # so, here's a test case without anno +ying the router @int_descriptions = ( 'foo.baz 12.247.62.7 20140608:1629', 'royal.com 1.11.617.251 20140608:1457', 'harvard.edu 1.1.217.0 20140608:1454', 'smithbarney.fin 195.7.168.2 20140608:1454', 'pomono.edu 93.16.124.5', 'yale.edu 58.3.179.6', 'etc.org 9.11.14.0 20140608:1320', ); open my $fh, '<', 'foo1089209.txt' or die "Can't open file for read, $ +!"; my @foo = <$fh>; for my $foo(@foo) { chomp $foo; say " *** Testing for matches to \$foo: $foo ***"; for (@int_descriptions) { my $int = qr/$_/; if ( $int =~ /$foo/ ) { say "\t \$foo: $foo found in \$int: $int"; } } # next; }

    where foo1089209.txt looks like this:

    my test file foo.bar pomona.edu wesleyan.edu harvard.edu yale.edu mit.edu oberline.edu foo.com bar.org smithbarney.fin ebay.co ebay.com

    Which give you, as output:

    *** Testing for matches to $foo: my test file foo.bar *** *** Testing for matches to $foo: pomona.edu *** *** Testing for matches to $foo: wesleyan.edu *** *** Testing for matches to $foo: harvard.edu *** $foo: harvard.edu found in $int: (?^u:harvard.edu 1.1.217.0 2 +0140608:1454) *** Testing for matches to $foo: yale.edu *** $foo: yale.edu found in $int: (?^u:yale.edu 58.3.179.6) *** Testing for matches to $foo: mit.edu *** *** Testing for matches to $foo: oberline.edu *** *** Testing for matches to $foo: foo.com *** *** Testing for matches to $foo: bar.org *** *** Testing for matches to $foo: smithbarney.fin *** $foo: smithbarney.fin found in $int: (?^u:smithbarney.fin 195 +.7.168.2 20140608:1454) *** Testing for matches to $foo: ebay.co *** *** Testing for matches to $foo: ebay.com ***

    But -- that's not the most elegant of solutions.



    Quis custodiet ipsos custodes. Juvenal, Satires

      Thanks. This may be a more inelegant solution, but I really only need quick-and-dirty in this case, and I think it'll be the easiest to implement.