There is a problem with zgrep whenever the -f option actually reads from the output of a process substition in bash.
A willingly trivial example below.
$ mkdir /tmp/test
$ cd /tmp/test
$ cat > first
$ cat > second
$ cat > third
$ cat > fourth
$ tail *
==> first <==
==> fourth <==
==> second <==
==> third <==
$ gzip -9 *
first.gz fourth.gz second.gz third.gz
$ cat > patterns
$ tail patterns
$ zfgrep -f <( cat patterns ) first.gz fourth.gz second.gz third.gz
$ zfgrep -f patterns first.gz fourth.gz second.gz third.gz
zfgrep -f <( cat patterns ) first.gz fourth.gz second.gz third.gz
zfgrep -f /dev/fd/XX first.gz fourth.gz second.gz third.gz
where XX is a number, 63 for instance .
The problem, from what I understand, arises since
zgrep -f patternfile a.gz b.gz c.gz
actually is a succession of
gzip -dc a.gz | grep -f patternfile
gzip -dc b.gz | grep -f patternfile
gzip -dc c.gz | grep -f patternfile
Since patternfile in this case is /dev/fd/XX, only the first invocation of grep in the first pipeline actually reads a pattern list, while the second and third invocation get nothing, giving no match for b.gz and c.gz as a result.
From /bin/zgrep (Version 1.6, Ubuntu 15.10) one can read
(-f | --file)
# The pattern is coming from a file rather than the command-line.
# If the file is actually stdin then we need to do a little
# magic, since we use stdin to pass the gzip output to grep.
# Turn the -f option into an -e option by copying the file's
# contents into OPTARG.
case $optarg in
(" '-'" | " '/dev/stdin'" | " '/dev/fd/0'")
optarg=" '"$(sed "$escape") || exit 2;;
The workaround concerning stdin should (maybe) also apply to situations such as the one in my example?
Thanks in advance.