13.3. Finding Text That Doesn't Match
I used this most recently when working on this book. We have thousands of separate files under RCS (Section 39.5), and I sometimes forget which ones I've got checked out. Since there's a lot of clutter in the directory and several people working there, a simple ls won't do. There are a series of temporary files created by some of our printing scripts that I don't want to see. All of their filenames consist of one or more x characters: nothing else. So I use a findpt alias to list only the files belonging to me. It's a version of the find. alias described in Section 9.26, with -user tim added to select only my own files and a grep pattern to exclude the temporary files. My findpt alias executes the following command line:
find. | grep -v '^\./xx*$'
The leading ./ matches the start of each line of find. output, and xx* matches one x followed by zero or more x s. I couldn't use the find operators ! -name in that case because -name uses shell-like wildcard patterns, and there's no way to say "one or more of the preceding character" (in this case, the character x) with shell wildcards.
Obviously, that's as specific and nonreproducible an example as you're likely to find anywhere! But it's precisely these kinds of special cases that call for a rich vocabulary of tips and tricks. You'll never have to use grep -v for this particular purpose, but you'll find a use for it someday.
[Note that you could use a slightly simpler regular expression by using egrep (Section 13.4), which supports the plus (+) operator to mean "one or more," instead of having to use the basic regular expression character character zero-or-more (xx*). The previous regular expression would then become:
find. | egrep -v '^\./x+$'
The richer regular expression language is the primary advantage of egrep. -- DJPH]
Copyright © 2003 O'Reilly & Associates. All rights reserved.