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

I am completely new to Perl and would like some feedback/assistance. Hoping I don't make anyone cringe too badly.

Trying to open a list and use each item on the list to bring out information on that item from the open file. Items will be listed in the second column of the file, but if the item matches I need to print all columns for that file.

When I list all the items out directly in my code instead of opening the list, the code works. However, when I add the element of opening the list, I get no readout whatsoever.

There are no warnings, so I can't figure out what's wrong. The format of my list maybe?

#! C:\Perl\bin\perl -w open (LIST, "List.txt" ); @mylist = (<LIST>); open (FILE, "FILE.txt" ); @myfile = (<FILE>); foreach $file(@myfile) { foreach $list(@mylist) { @temp = split (/\t/, $file); chomp @temp; if ( $temp[1] eq $list ) {print ("$file")} } }

Replies are listed 'Best First'.
Re: Looping in a Loop
by Athanasius (Archbishop) on Sep 16, 2014 at 13:24 UTC

    Hello Violet, and welcome to the Monastery!

    Although there is nothing wrong with your approach, a more idiomatic or “Perlish” way to do this would be to use a hash for the look-up. Here’s a little script to illustrate:

    #! perl use strict; use warnings; my @list = qw( Wilma Betty ); my %lookup = map { $_ => undef } @list; while (my $line = <DATA>) { my @fields = split /\s+/, $line; next unless defined $fields[1]; print $line if exists $lookup{$fields[1]}; } __DATA__ Fred Wilma Pebbles Dino Barney Betty Bamm-Bamm Homer Marge Bart Lisa Maggie George

    Output:

    23:18 >perl 1015_SoPW.pl Fred Wilma Pebbles Dino Barney Betty Bamm-Bamm 23:18 >

    Please note the line:

    use strict;

    Get in the habit of including this in all your scripts, and it will save you a lot of debugging time in the long run. (Essentially, it just means you will need to put my before each variable the first time that variable is used in the script.)

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Looping in a Loop
by toolic (Bishop) on Sep 16, 2014 at 12:53 UTC
Re: Looping in a Loop
by LanX (Saint) on Sep 16, 2014 at 12:57 UTC
    You didn't show us samples of the files, so I can only guess that end-of-line characters might be the problem.

    You should chomp both read lines or alternatively @mylist and @myfile, but only chomping @temp looks strange.

    If this doesn't help try Data::Dumper to inspect your data.

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: Looping in a Loop
by johngg (Canon) on Sep 16, 2014 at 14:08 UTC

    Another habit you should get into is to check for success when you open a file and print the o/s error held in $! on failure.

    $ perl -Mstrict -Mwarnings -E ' > open my $inFH, q{<}, q{doesNotExist} > or die qq{open: < doesNotExist: $!\n};' open: < doesNotExist: No such file or directory $

    Welcome to the Monastery and the world of Perl!

    Cheers,

    JohnGG

Re: Looping in a Loop
by VinsWorldcom (Prior) on Sep 16, 2014 at 13:39 UTC

    UPDATE: Athanasius beat me to the punch with both a 'welcome' and a better 'Perl-ish' solution!

    Violet, first off, welcome to the Monastery and to the wonderful world of Perl programming.

    First off, start all your scripts with 'use strict' and 'use warnings', that will help you catch many errors and incorrect or troubling syntax that may impact your output and obfuscate troubleshooting.

    You should use the three-argument 'open' for better security in your code.

    The main problem I see is that you operate on FILE while in the LIST loop. You should do the operations on FILE outside the LIST loop. I've provided reference below that works on a small test data set I made up (assuming what your input files look like based on your question and code).

    #! C:\Perl\bin\perl -w use strict; use warnings; open my $LIST, '<', "list.txt"; my @mylist = <$LIST>; open my $FILE, '<', "file.txt"; my @myfile = <$FILE>; foreach my $file (@myfile) { chomp $file; my @temp = split (/\t/, $file); foreach my $list (@mylist) { chomp $list; if ($temp[1] eq $list) { print "$file\n" } } }