1

First, I try the following code

find . -name "*.cfg" | xargs grep "good"|grep -v "^\#"

In the current folder, I get the list with the file name's extension is "cfg". Then I want to search the contents to find lines containing the "good" but not begin with "#" . But my code doesn't work. Is there something wrong? Thank you.

2 Answers 2

3

Useless use of xargs (if your find has -exec):

find . -name "*.cfg" -exec egrep "^[^#]*good" {} +

The caret doesn't need to be masked - I don't know any circumstance where it has to be. But it isn't of harm and your whole command works for me.

4
  • You should use execplus instead of exec.
    – schily
    Commented Dec 8, 2015 at 16:25
  • 2
    @schily: Why? Execplus has to be pretty new - I've never seen it before. I'm using find (GNU findutils) 4.4.2. Or do you mean -exec ... + ? Well, you can, yes. Premature optimization is the root of all evil. :) Commented Dec 8, 2015 at 16:31
  • execplus exists since 1989, gfind seems to have overslept the last 20 years of UNIX development.
    – schily
    Commented Dec 8, 2015 at 16:34
  • execplus is the common way of naming -exec ... + since David Korn introduced it in 1989.
    – schily
    Commented Dec 8, 2015 at 16:41
1

Something like the following should work:

find . -name "*.cfg" -print0 | xargs -0 grep -E '^([^#].*|)good'

Note that I switched to -print0 to avoid problems with file names containing white space.

Then I filter lines containing good but not starting with # in a single regexp. The left alternative ([^#].*) matches lines that begin with a non-# character, wheres the right alternative (empty) allows matching lines that begin with good.

Using a single regexp, rather than two as in your question, allows us to let GNU grep print file names (which it will do if more than one file is provided by find). Adding grep -v ^... in a second step would fail to match the beginning of the file's lines.

2
  • Thank you, I like this code, because it shows which file it contains the string.
    – yuxuan
    Commented Dec 8, 2015 at 16:20
  • 1
    Oh yes, I forgot to mention that this was a reason for using a single regexp: the code in your question will not work when more than one file is matched by the first call to grep, because then GNU grep will prepend file names, preventing the call to grep -v from properly matching start-of-line patterns.
    – dhag
    Commented Dec 8, 2015 at 16:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .