You'll need to use something more capable than grep
, which can only do single-line matches.
perl
, which can do multi-line matches, is perfect for this kind of job, combined with find
to generate the list of files to search.
find dir/ -type f -iname '*.txt' -exec perl -e '
local $/; # slurp in entire files, instead of one line at a time
my $firstfile = shift @ARGV; # get name of the first file
open(F,"<",$firstfile) or die "Error opening $firstfile: $!";
my $first = <F>; # read it in
close(F);
my $search = qr/\Q$first\E/; # compile to a fixed-string RE
# now read in remaining files and see if they match
while(<>) {
next if ($ARGV eq $firstfile);
if (m/$search/m) {
print $ARGV,"\n";
};
}' ./compromised_header.txt {} +
This prints the filenames of any *.txt files in or below dir/
that contain the exact text in the first file ("compromised_header.txt").
Notes:
the qr//
operator compiles a regex. The main use for this is to pre-compile an RE before using it in a loop, so that it doesn't waste time and cpu cycles getting re-compiled on every pass through the loop.
the \Q
and \E
used in the qr//
operation mark the beginning and end of text in an RE pattern that is meant to be interpreted as a fixed string - i.e. all meta-characters that might be in the string will be quoted to disable their special meaning. See man perlre
and search for "Quoting metacharacters" and perldoc -f quotemeta
for details.
If that seems like an ugly, complicated, unreadable one-liner then try it like this, as a standalone script:
#!/usr/bin/perl
local $/; # slurp in entire files, instead of one line at a time
my $firstfile = shift @ARGV; # get name of the first file
open(F,"<",$firstfile) or die "Error opening $firstfile: $!";
my $first = <F>; # read it in
close(F);
my $search = qr/\Q$first\E/; # compile to a fixed-string RE
# now read in remaining files and see if they match
while(<>) {
next if ($ARGV eq $firstfile);
if (m/$search/m) {
print $ARGV,"\n";
};
}
Save this as, e.g., check.pl
and make it executable with chmod +x check.pl
. Then run:
find dir/ -type f -iname '*.txt' \
-exec ./check.pl ./compromised_header.txt {} +