With perl
:
if perl -0777 -e '$n = <>; $h = <>; exit(index($h,$n)<0)' needle.txt haystack.txt
then echo needle.txt is found in haystack.txt
fi
-0octal
defines the record delimiter. When that octal number is greater than 0377 (the maximum byte value), that means there's no delimiter, it's equivalent to doing $/ = undef
. In that case, <>
returns the full content of a single file, that's the slurp mode.
Once we have the content of the files in two $h
and $n
variables, we can use index()
to determine if one is found in the other.
That means however that the whole files are stored in memory which means that method won't work for very large files.
For mmappable files (usually includes regular files and most seekable files like block devices), that can be worked around by using mmap()
on the files, like with the Sys::Mmap
perl module:
if
perl -MSys::Mmap -le '
open N, "<", $ARGV[0] || die "$ARGV[0]: $!";
open H, "<", $ARGV[1] || die "$ARGV[1]: $!";
mmap($n, 0, PROT_READ, MAP_SHARED, N);
mmap($h, 0, PROT_READ, MAP_SHARED, H);
exit (index($h, $n) < 0)' needle.txt haystack.txt
then
echo needle.txt is found in haystack.txt
fi