Perl: Match pattern and print next N lines K times
I have a text file similar to this
count="4" data1 data2 data3 Data1 Data2 Data3
I need to find a string count
and take its value (4) and print the next 3 lines (4) times.
The output in the file should be
data1
data2
data3
data1
data2
data3
data1
data2
data3
data1
data2
data3
Data1
Data2
Data3
I have tried this Perl code
while ( <FILE> ) {
$n = 3
if ( $_ =~ /count="4"/ ) {
print FILE if ($n-- > 0) x 4;
}
But it doesn't work.
+3
source to share
4 answers
But it doesn't work.
It's because
if ($n-- > 0) x 4
doesn't do what you want. x
repeats the value (i.e. you do if 1111
), it doesn't repeat the statement.
Try:
use strict; use warnings;
while (<FILE>) {
if ( /count="(\d+)"/ ) {
for ( 1..$1 ) {
if ( defined ( my $l = <FILE> ) ) {
print $l;
}
}
}
}
This will help you get started.
In the future, please note:
- Instead of "not working". Give the actual result (even if all you can say is "prints nothing and throws no errors")
- When something doesn't work, consider the perl debugger
- Notice
use strict;
anduse warnings;
- this will help you avoid mistakes . - Learn about capturing perlre and $ 1 and other regex related perlvar variables
+4
source to share
you can point the file / input to @data
#!/usr/bin/perl
use strict;
use warnings;
my @data = qw /count="4" data1-1 data2-1 data3-1 Data1 Data2 Data3/;
my $repeat_line = 3;
foreach (@data)
{
if ( /count="(\d+)"/ ) {
for ( 1..$1 ) {
for my $no1 ( 1..$repeat_line ) {
print $data[$no1],"\n";
}
}
}
}
for my $no ($repeat_line..scalar(@data)) {
if(defined $data[$no+1]){
print $data[$no+1],"\n";
}
}
Output
data1-1 data2-1 data3-1 data1-1 data2-1 data3-1 data1-1 data2-1 data3-1 data1-1 data2-1 data3-1 Data1 Data2 Data3
0
source to share
You can use this one liner:
perl -ne 'print m/count="(\d+)"/?$n=(<>.<>.<>)x$1:$_' file
# ^ ^ ^ ^ ^^---- the current line.
# | | | | '---- else
# | | | '---- repeated $1 times
# | | '---- the three next lines (if any) stored in $n
# | '---- when this pattern succeeds,
# '---- Print,
0
source to share