Reputation: 47
I have the following code:
#!/usr/bin/perl
open (FH, "input.txt") or die $!;
my @contents = <FH>;
my $count = 0;
map
{
$count ++;
if($_ =~ /This/)
{
print "\nNext 3 lines:\n$contents[$count+1] $contents[$count+2] $contents[$count+3]";
}
} @contents;
Summary of program: 1. Get an input file. 2. If the line contains 'This', then print the next 3 lines.
I was wondering how can I modify the print statement to show the array contents using range. That is, something like below:
print "\nNext 3 lines:\n$contents[$count..$count+3]";
Can anyone point out what is the right way to achieve this?
PS: My problem here is in showing array range. Please don't discuss the efficiency of the program.
Upvotes: 1
Views: 528
Reputation: 69244
The syntax that you want is
@contents[$count..$count+3]
It's called an array slice.
But you probably want something like:
@contents[$count..min($count+3, $#count)]
to avoid falling off the end of the array.
And please don't use map
in void context like that. If you're not using the return value from map
then foreach
(or for
) is far less confusing for the people who need to maintain your code later (even if that's you in two weeks time).
Update: In the comments, @DaveVogt just pointed out that your count starts from 1 rather that the more common 0. The easiest way to get round that is probably to move the $count++
to the end of the loop body.
So here's how I'd write it (well, it's probably not how I'd write it at all - but it's how I'd write it starting from your version).
#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'min';
open my $in_fh, 'input.txt' or die $!;
my @contents = <$in_fh>;
my $count = 0;
foreach (@contents) {
if (/This/) {
next if $count >= $#contents;
my $end = min($count+3, $#contents);
print "\nNext three lines: @contents[$count+1..$end]";
}
$count++;
}
Upvotes: 3
Reputation: 6578
#!/usr/bin/perl
use warnings;
use strict;
my @lines = ('one', 'two', 'This line', 'That line', 'Other line', 'Last line', 'three', 'four');
my $count = 0;
foreach(@lines){
$count = 4 if /This/;
print "$_\n" if ($count-- > 0);
}
On reading through your array this will set $count
to 4
on encountering a This
, and will print the line until $count -1
is > 0 (i.e. the first incidence prints the line itself, and then the next 3 lines)
Upvotes: 3