GNU bug report logs - #26576
-v when used with -C

Previous Next

Package: grep;

Reported by: 積丹尼 Dan Jacobson <jidanni <at> jidanni.org>

Date: Thu, 20 Apr 2017 14:40:01 UTC

Severity: normal

Tags: notabug

Done: Eric Blake <eblake <at> redhat.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Eric Blake <eblake <at> redhat.com>
To: 積丹尼 Dan Jacobson <jidanni <at> jidanni.org>
Cc: 26576-done <at> debbugs.gnu.org
Subject: bug#26576: -v when used with -C
Date: Thu, 20 Apr 2017 11:26:47 -0500
[Message part 1 (text/plain, inline)]
On 04/20/2017 10:37 AM, 積丹尼 Dan Jacobson wrote:
> I want to do
> $ cat file|some_program
> but I must must exclude the UGLY line and its two neighbors.
> 
> OK I have found the UGLY line, and its two neighbors
> $ grep -C 2 UGLY file
> bla
> bla
> UGLY
> bla
> bla
> 
> but I have no way to exclude them before piping to some_program.

So it sounds like you are asking for some sort of new --invert-output,
which toggles which lines to display.  Revisiting my example, it would
change:

$ seq 10 | grep -C 2    5
3
4
5
6
7

into:

$ seq 10 | grep -C 2    5 --invert-output
1
2
--
8
9
10

as well as:

$ seq 10 | grep -C 2 -v 5
1
2
3
4
5
6
7
8
9
10
$ seq 10 | grep -C 2 -v '[3-8]'
1
2
3
4
--
7
8
9
10

into:

$ seq 10 | grep -C 2 -v 5 --invert-output
$ seq 10 | grep -C 2 -v '[3-8]' --invert-output
5
6

It's very corner case, so I'm not sure it's worth burning an option and
complicating grep to do this, plus waiting for a future version of grep
with the proposed new option to percolate to your machines, when you
already accomplish the same task using existing tools (admittedly with
more complexity).

For example, you can use sed twice if the data is in a file that can be
re-read or easily regenerated (in this case, I'm skipping d, h, and any
line within -C1 of the ugly lines):

$ printf %s\\n a b c d e f g h i j > file
$ ugly=$(sed -n '/[dh]/ =' file)
$ sed "$(for line in $ugly; do echo "$((line-1)),$((line+1))d;";
   done)" file
a
b
f
j

Or it should be easy enough to write an awk script that stashes all
input lines into one array, then checks for regular expression matches,
and sets multiple entries in a corresponding poison array to 1 (based on
how many lines of context you want to poison), then in an END block only
print out lines if the corresponding poison[] entry is not 1.  Although
I'll leave that as an exercise for the reader.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

[signature.asc (application/pgp-signature, attachment)]

This bug report was last modified 8 years and 35 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.