Based on your description, something like this might be a good start. It assumes you can run a pipeline command that feeds the list of file names to the perl script's STDIN - e.g. using a bash shell with standard GNU/linux utils, a command line like this:
cd {top_level_directory_where_all_files_are_located}
find * -type f | search_script.pl > hit_list.txt
And "search_script.pl" would be something like this:
#!/usr/bin/perl
use strict;
use warnings;
while (<STDIN>) {
chomp;
next unless -f();
my $text = do {
if ( open( my $fh, $_ )) {
local $/;
<$fh>;
}
else {
warn "Unable to read $_\n";
}
};
if ( $text =~ /\s(recommend\S*\s+to\s+vote\s+\S+)/ ) {
( my $hit = $1 ) =~ s/\s+/ /g;
print "$_: $hit\n";
}
else {
print "$_: NO_MATCH\n";
}
}
Note that in bash you can redirect STDERR as well:
find * -type f | search_script.pl > hit_list.txt 2> search.errlog
The output to STDOUT will tell you which files have the sought-for text, and what the text was. It also lists the files that failed to match, so you can take a closer look at those, and tweak the regex as needed.
The regex proposed above will match all the inflections on "recommend" (-ed, -ing, -s, -ation), and will capture the matched phrase only up to the word that follows "vote". (You can extend the capture to include more words before and/or after, if you like, by adding more \s+\S+\s+ elements inside the parens.)
When there's a match, all kinds of white-space between words is allowed, and it's all normalized to a single space before output, to ensure one line of output per file.