Search code examples
shellgrepackpiping

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 ack?

I can do:

ack "foo" | grep -v "bar"

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


Solution

  • 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