Operating System - Linux
1753347 Members
4919 Online
108792 Solutions
New Discussion юеВ

Re: a better way to exclude items other than a series of "grep -v" piped commands

 
SOLVED
Go to solution
Hein van den Heuvel
Honored Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

John,

It's actuallly no problem as I had it already written up two weeks ago.
And it is not perfect....

http://dcl.openvms.org/stories.php?story=07/03/22/8049141

There are more differences with the VMS version that I did not take care of.
- VMS needs to special case ";" as file version seperator
- and VMS typically is case-blind for filenames (Unless ODS-5 is used)
- VMS is strict about extentions allowing just 1 dot in the file name (unless ODS-5).

=> The ; provided a 'right side' anchor for the regexp. Need to use $ for "eol" under Unix.
=> Need to allow for multiple dots.

This gives:

$ perl -le 'while (<*>) {$seen{$1}++ if /\.([^.]*$)/} print "\\.$_" foreach (sort keys %seen)'

Explanation:

-l = print new line with each print

-e = program text to follow

while (<*>) { = loop over 'globbed' list of files, putting filename in automatic variable $_

$seen{uc($1)}++ = Increment (and create) an associative array elemement with name being last match from $1

if /\.([^.]*$)/ = Only do the aforementioned on a match of a piece of string to be called $1 with 'any non dot' after a period and before end of line. The first period is escaped with a backslash to make it real, not a wild character

} = loop end

print = print the default variable $_

foreach (sort = loop over sorted array from...

keys %seen = all the keys for associative array 'seen', stashed in default variable $_ one at a time.

Regards, Hein van den Heuvel

TwoProc
Honored Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

Hein, thank you very much for the posting, now I've got something to go to the books with and review. That was graciously posted, thank you.

I was laughing to myself looking over the code aspects as you've written them; because had I written them in Perl, they would have come out being a) MUCH longer, and b) looking like someone who is used to writing in both C and ksh "wrote a combination C/ksh script in perl".
:-)
We are the people our parents warned us about --Jimmy Buffett
Dennis Handly
Acclaimed Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

>handling it all in a single grep from the command line ...

Your only problem was you only need one -v and the -e must be right before each pattern.
And if you didn't want to quote those ".", use fgrep.

>Patrick: # find . -type f | grep -v -E "\.xml|\.gif|\.htm|\.html"

There is no reason to use the egrep hammer.
Just use -f for that file solution. Or use multiple -e:
grep -v -e "\.xml$" -e "\.gif$" ...
TwoProc
Honored Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

Denis,

thanks for your response - however a bit of clarification here is needed. I said that the "grep -v -e" doesn't work, and it doesn't , at least in HPUX 11i (might work in the newer ones).

So, while the "grep -v -e" in repetition works fine in Linux, it does not on HPUX:

example:

$ cat > test
ehlllo
goodbye
bye
hello
no
yes
sayit
say
yell
scream
ice cream
ice
cream

$ cat test | grep -v -e "test" -v -e "yell" -v -e "ice"
ehlllo
goodbye
bye
hello
no
yes
sayit
say
yell
scream
ice cream
ice
cream

Notice that no lines are missing:

HOWEVER, on Linux the above test works as expected:

$ cat test | grep -v -e "test" -v -e "yell" -v -e "ice"
ehlllo
goodbye
bye
hello
no
yes
sayit
say
scream
cream

Which is why I put the question in the HPUX forum...
We are the people our parents warned us about --Jimmy Buffett
James R. Ferguson
Acclaimed Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

Hi John:

The '-v' switch needs to occur *once*:

# grep -v -e "test" -e "yell" -e "ice" file

By the way, you can skip the extra process (the 'cat') and let 'grep' open the file(s) specified as its argument(s) as above.

Regards!

...JRF...
OldSchool
Honored Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

"Note: handling it all in a single grep from the command line in the following fashion with something like "grep -e -v "\.gif" -e -v "\.htm" doesn't work."

Actually, as noted above, it should be:

grep -v -e "\.gif" -e "\.html" .....

w/o repeating "-v".

Unfortunately, Linux isn't unix, its a work-alike, developed from observed behaviour / documentation of unix + "enhancements"
TwoProc
Honored Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

Well then,
it looks like the Linux version has figured out how to ignore the repeatiing series of "-v" to make it work...

thanks all for the clarification,
and I see that re-reading Dennis' post, he didn't repeat the "-v" over and over again.

Sorry Dennis, wish they had a do-over button on the points.
We are the people our parents warned us about --Jimmy Buffett
Dennis Handly
Acclaimed Contributor

Re: a better way to exclude items other than a series of "grep -v" piped commands

>I see that re-reading Dennis' post, he didn't repeat the "-v" over and over again.

I would assume you could repeat it and work, but I'm lazy. You just can't put the -v after the -e.

Ah, you're right, there is a bug in grep. They just increment vflag then they do bit stuff on it.

>Sorry Dennis, wish they had a do-over button on the points.

Ok, you can add the rest here. :-)
So you don't feel short changed, I filed a bug report on it:
CR JAGag37626:
Multiple -v in grep cause all to be ignored