I have been searching for a solution that allows me to search the lines of an array, and if a string match is made, push that line and the 2 previous lines into an array. It
You are mixing up the grep program /bin/grep
with the perl function named grep
(perldoc -f grep
). While the former takes additional parameters, like -B
, the latter does not.
A basic version of your subroutine. I assume you wanted to return the list when done with it. Untested.
sub ipsearch {
my $ip = shift;
my @IPVSCONFIG = (); # no matches should be empty list, not undef
my @buffer = () # to avoid undef warnings
for (@RAWDATA) {
push @buffer, $_;
shift @buffer if @buffer > 3;
if (/\W+virtual\s$ip\s/) {
push @IPVSCONFIG, @buffer;
@buffer = ();
}
}
return @IPVSCONFIG;
}
The trick is to identify the lines where the match occurs, then identify the relevant indices around:
Get the matched indices:
my @matchedIndices = grep { $RAWDATA[$_] =~ /\W+virtual\s$ip\s/ } 2 .. $#RAWDATA;
Get the indices around:
my @wantedIndices = map { ( $_-2 .. $_ ) } @matchedIndices;
And take an array slice:
my @IPVSCONFIG = @RAWDATA[ @wantedIndices ];
Putting it altogether in a Schwartzian transform:
my @IPVCONFIG = map { @RAWDATA[$_-2..$_] }
grep { $RAWDATA[$_] =~ /\W+virtual\s$ip\s/ }
2 .. $#RAWDATA ;
Definitely a much busier solution than the traditional command-line grep -B 2
!