Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Busting out of an inner loop to next file in foreach loop

by biohak (Initiate)
on Mar 10, 2014 at 14:00 UTC ( [id://1077685]=perlquestion: print w/replies, xml ) Need Help??

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

Apologies if this is a newbie question, I havent been able to find a solution online. I have a loop that iterates through an array of filenames and I would like to break out of a nested loop to the next file in @filnames. I must be overlooking a simple solution or method that I am not aware of. I added the goto statement hoping to return to the outer loop, but I found this just restarts from the beginning of the foreach which is not what I wanted. edit: I noticed the label was on the line above the foreach loop. After moving inline with the loop, it is working properly. Thanks for the help, TIA

RECORD: foreach my $filenames (@filenames) { my $XML_infile = "C:/_OUTPUT/$filenames"; chomp $XML_infile; open INDATA, "C:/_OUTPUT/$filenames" or die "INDATA: $! \n\n "; while (!eof INDATA ) { my $line = <INDATA>; if ( $line =~ /\"PlateID\"/g ) { $outfile= ">C:/_OUTPUT/_DATA/$filenames" . $plate_id . ".t +xt"; if ( ($plate_id eq '' ) or ( ($FAM eq '' ) && ($VIC eq '' +) ) ) { popup_error_window($XML_infile) ; #Jump to next file in @filenames from here next RECORD; #Duh was staring right at me. } elsif () {#pull data for PlateID} } elsif () {#Process rest of file } } #complete processing data }#endforeach

Replies are listed 'Best First'.
Re: Busting out of an inner loop to next file in foreach loop
by choroba (Cardinal) on Mar 10, 2014 at 14:04 UTC
    If you want to start the next iteration of a loop that has the label NEXTRECORD, just use
    next NEXTRECORD;

    As you can see, naming the label just RECORD might make more sense.

    BTW, what is that goto supposed to do?

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      chorba, Thanks, was starting at me and I couldn't see it

        you changed the OP w/o indication. :(

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: Busting out of an inner loop to next file in foreach loop
by LanX (Saint) on Mar 10, 2014 at 14:22 UTC
    I think you are looking for "last", in your code example you don't even need a label.

    HTH! :)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    > I havent been able to find a solution online.

    duckduckgo or google "perl break loop"

Re: Busting out of an inner loop to next file in foreach loop
by kcott (Archbishop) on Mar 11, 2014 at 05:09 UTC

    G'day biohak,

    Welcome to the monastery.

    Firstly, please don't alter your OP without indicating what you've changed. See "How do I change/delete my post?" for an explanation of why not and how to indicate changes.

    The code you currently have posted has many issues:

    • "RECORD: foreach my $filenames (@filenames) {": The label is unnecessary (as ++LanX has pointed out) and each element of @filenames is one filename so let the variable reflect this, i.e. $filename.
    • "chomp $XML_infile;": This appears to be doing nothing: see chomp.
    • "open INDATA, "C:/_OUTPUT/$filenames" or die "INDATA: $! \n\n ";": Use the 3-argument form of open with a lexical filehandle; you already have the file path in $XML_infile so use it here; your die message should contain a filename (INDATA is a filehandle) — alternatively, use the autodie pragma.
    • "while  (!eof INDATA ) {": There's no need for eof here, just read from the filehandle (optionally assigning to a variable). See "perlsyn: Loop Control".
    • "my $line = <INDATA>;": See last point.
    • "if ( $line =~ /\"PlateID\"/g ) {": The 'g' modifier is for repeat matching which isn't what you're doing here. See "perlre: Modifiers".
    • "$outfile= ">C:/_OUTPUT/_DATA/$filenames" . $plate_id . ".txt";": You haven't assigned a value to $plate_id.
    • "next RECORD;": last is what you need here (as LanX has pointed out).
    • "elsif () {#pull data for PlateID}": It looks like that should be else {...}. See "perlsyn: Compound Statements".
    • "elsif () {#Process rest of file }": This looks unnecessary: I see no need for either elsif or else here.

    Using this dummy data (as I've no idea what your real data looks like):

    $ cat pm_1077685_A.txt Line 1: no plate info Line 2: ... PlateID 123 ... Line 3: ... PlateID 456 ... Line 4: no plate info $ cat pm_1077685_B.txt Line 1: no plate info Line 2: ... PlateID 789 ... Line 3: ... PlateID ... Line 4: no plate info $ cat pm_1077685_C.txt Line 1: no plate info Line 2: ... PlateID 000 ... Line 4: no plate info

    This script shows similar processing to what you appear to be attempting and includes examples of the points I've made above.

    #!/usr/bin/env perl use strict; use warnings; use autodie; my @filenames = qw{pm_1077685_A.txt pm_1077685_B.txt pm_1077685_C.txt} +; for my $filename (@filenames) { my $in_path = "./$filename"; print "Processing: '$in_path'\n"; open my $in_fh, '<', $in_path; while (<$in_fh>) { print "\t$_"; if (/PlateID/) { if (/PlateID (\d+)/) { my $plate_id = $1; print "\t\tProcess PlateID '$plate_id' from '$in_path' +\n"; } else { print "\t\tpopup_error_window($in_path)\n"; last; } } } }

    Output:

    $ pm_example.pl Processing: './pm_1077685_A.txt' Line 1: no plate info Line 2: ... PlateID 123 ... Process PlateID '123' from './pm_1077685_A.txt' Line 3: ... PlateID 456 ... Process PlateID '456' from './pm_1077685_A.txt' Line 4: no plate info Processing: './pm_1077685_B.txt' Line 1: no plate info Line 2: ... PlateID 789 ... Process PlateID '789' from './pm_1077685_B.txt' Line 3: ... PlateID ... popup_error_window(./pm_1077685_B.txt) Processing: './pm_1077685_C.txt' Line 1: no plate info Line 2: ... PlateID 000 ... Process PlateID '000' from './pm_1077685_C.txt' Line 4: no plate info

    -- Ken

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-04-19 20:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found