my %ignore; # First pass while () { $ignore{$1} = 1 if some_condition($_); } # Second pass # reset the file to the beginning seek FH, 0, 0; while () { if (m/matches interesting string with (capture)/) { if (exists($ignore{$1}) { next; # don't print this line print; } #### my $in_paragraph; my $bar; my %ignore; while () { if (m/start of paragraph/) { $in_paragraph = 1; $bar = 0 next; } if (m/end of paragraph/) { $in_paragraph = 0; next; } if (m/line with bar/) { $bar = 1; next; } if (m/line with ref (\d+)/) { if ($begin and $bar and not $end) { $ignore{$1} = 1; } next; } }