in reply to Find the first occurance and if not found print the first line

As I understand what you are doing, the problem with your approach is that in the third Query there are three gi lines but the ref is in the second gi line. Your logic to determine if a sequence of gi lines has a ref in it is faulty because it will only check the first gi line (once you detect a gi line you gobble up the rest of them.)

Here's an approach which sub-divides the problem into parsing a Query and then processing it:

use Data::Dumper; my $query; while (<IN>) { if (s/^Query=\s*//) { my $save = $_; process($query); } $query = { query_line => $save }; } elsif (m/(\d+)\s*letters/) { $query->{letters} = $1; } elsif (m/^gi/) { push(@{$query->{gi_lines}}, $_); } } process($query); sub process { print Dumper($_[0]); # for now }
Now you can examine all of the gi lines in a query:
sub process { my $query = shift; return unless $query; # first time $query will be undef ... # iterate through all the gi lines for my $gi_line (@{$query->{gi_lines}}) { if ($gi_line =~ m{\|ref\|}) { ... ref found ... } } }
This way it should be easier to implement whatever processing logic you need.