Hello.
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
aaa
$ cat > second
bbb
$ cat > third
ccc
$ cat > fourth
ddd
$ tail *
==> first <==
aaa
==> fourth <==
ddd
==> second <==
bbb
==> third <==
ccc
$ gzip -9 *
$ ls
first.gz fourth.gz second.gz third.gz
$ cat > patterns
aaa
bbb
ccc
ddd
$ tail patterns
aaa
bbb
ccc
ddd
$ zfgrep -f <( cat patterns ) first.gz fourth.gz second.gz third.gz
first.gz:aaa
$ zfgrep -f patterns first.gz fourth.gz second.gz third.gz
first.gz:aaa
fourth.gz:ddd
second.gz:bbb
third.gz:ccc
zfgrep -f <( cat patterns ) first.gz fourth.gz second.gz third.gz
translates in
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'")
option=-e
optarg=" '"$(sed "$escape") || exit 2;;
esac
have_pat=1;;
The workaround concerning stdin should (maybe) also apply to situations such as the one in my example?
Thanks in advance.
Fulvio Scapin