Subject: Re: bug#26576: -v when used with -C

From: Eric Blake <[email-masked]>
Date: Thu, 20 Apr 2017 11:26:47 -0500

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