Jim Meyering wrote: > Thomas Bushnell, BSG wrote: >> Create a gzipped file: >> >> $ for i in $(seq 1 100); do echo $i; done > file.txt >> $ gzip file.txt >> >> Then: >> >> $ zgrep -9 17 file.txt.gz >> 8 >> 9 >> ... >> 25 >> 26 >> >> works. But: >> >> $ zgrep -10 17 file.txt.gz >> gzip: 17.gz: No such file or directory >> >> fails. >> >> Note that "grep -9 17 file.txt" and "grep -10 17 file.txt" work just >> fine. >> >> (https://bugs.launchpad.net/bugs/1032831) >> >> Please include me in the CC on any replies. > > Hi Thomas, > > Thanks for the report. > That made a nice puzzle to go with my morning caffeine ;-) > > Here's the fix: > I'll write the NEWS entry and test later.
Here's the complete patch I expect to push: >From 722184b17c98080c66453d4568bf37165108ad06 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Tue, 7 Aug 2012 10:21:55 +0200 Subject: [PATCH 1/2] zgrep: handle a multi-digit context option like -15 * zgrep.in: Do not malfunction when given an option like -15. Before, it could mistake the pattern for a file name: $ echo x | gzip | zgrep -15 x gzip: x.gz: No such file or directory * NEWS (Bug fixes): Mention it. Reported by Thomas Bushnell: https://bugs.launchpad.net/bugs/1032831 --- NEWS | 4 ++++ zgrep.in | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index ac39994..79c1110 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,10 @@ GNU gzip NEWS -*- outline -*- ** Bug fixes + zgrep no longer malfunctions with a multi-digit context option like -15. + Now, it passes that option to grep (equivalent to -C15) just as it does + for single-digit options. [bug introduced in gzip-1.3.12] + zmore now acts more like 'more', and is more portable to POSIXish hosts. diff --git a/zgrep.in b/zgrep.in index d09bfa7..abc5847 100644 --- a/zgrep.in +++ b/zgrep.in @@ -66,9 +66,13 @@ while test $# -ne 0; do case $option in (-[0123456789EFGHIKLPRTUVZabchilnoqrsuvwxyz]?*) - arg2=-\'$(expr "X$option" : 'X-.[0-9]*\(.*\)' | sed "$escape") - eval "set -- $arg2 "'${1+"$@"}' - option=$(expr "X$option" : 'X\(-.[0-9]*\)');; + if expr "X$option" : 'X-[0-9]\+$' > /dev/null; then + : # Let a multi-digit, digit-only option like -10 fall through. + else + arg2=-\'$(expr "X$option" : 'X-.[0-9]*\(.*\)' | sed "$escape") + eval "set -- $arg2 "'${1+"$@"}' + option=$(expr "X$option" : 'X\(-.[0-9]*\)') + fi;; (--binary-*=* | --[lm]a*=* | --reg*=*) ;; (-[ABCDXdefm] | binary-* | --file | --[lm]a* | --reg*) -- 1.7.12.rc1.22.gbfbf4d4 >From 71b69de01f6799280b9131bb5882971e53c99fcd Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Tue, 7 Aug 2012 18:29:14 +0200 Subject: [PATCH 2/2] tests: exercise the just-fixed part of zgrep * tests/zgrep-context: New file. * tests/Makefile.am (TESTS): Add it. --- tests/Makefile.am | 1 + tests/zgrep-context | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100755 tests/zgrep-context diff --git a/tests/Makefile.am b/tests/Makefile.am index 3b6ec31..ddab493 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,6 +25,7 @@ TESTS = \ trailing-nul \ zdiff \ zgrep-f \ + zgrep-context \ zgrep-signal \ znew-k diff --git a/tests/zgrep-context b/tests/zgrep-context new file mode 100755 index 0000000..85799a4 --- /dev/null +++ b/tests/zgrep-context @@ -0,0 +1,43 @@ +#!/bin/sh +# Ensure that zgrep -15 works. Before gzip-1.5, it would fail. + +# Copyright (C) 2012 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# limit so don't run it by default. + +. "${srcdir=.}/init.sh"; path_prepend_ .. + +require_POSIX_grep_ + +# A limited replacement for seq: handle 1 or 2 args, and an increment of 1. +seq() +{ + case $# in + 1) start=1 final=$1;; + 2) start=$1 final=$2;; + *) echo you lose 1>&2; exit 1;; + esac + awk 'BEGIN{for(i='$start';i<='$final';i++) print i}' < /dev/null +} + +seq 40 > in || framework_failure_ +gzip < in > in.gz || framework_failure_ +seq 2 32 > exp || framework_failure_ + +fail=0 +zgrep -15 17 - < in.gz > out || fail=1 +compare exp out || fail=1 + +Exit $fail -- 1.7.12.rc1.22.gbfbf4d4