SpaghettiCat SpaghettiCat - 1 month ago 4
Bash Question

How to specify an ignore pattern with ack?

I'm trying to search for lines containing 'foo' but these lines must not contain 'bar'. What's a good way to search with these parameters with


I can do:

ack "foo" | grep -v "bar"

but it doesn't keep the nicely layed-out and coloured output of
. Also,
doesn't have good support for Perl regexes, unlike


You can use a slightly more complicated regular expression:

ack '^(?!.*bar).*(foo)' file

The (?!...) does a negative lookahead to ensure that "bar" is not on the line. Here's how it works:

  • ^ Start at beginning of the line.
  • (?!.*bar) Advance any number of characters until "bar" is found. If it is found, do not continue. Otherwise, return to the start of the line and continue.
  • .*(foo) Match (and capture) "foo" at any point between the beginning and end of the line.

Testing it out:

$ cat file
other foo bar
baz foo other
$ ack '^(?!.*bar).*(foo)' file
baz foo other