19

I'm trying to grep through a bunch of files in nested subdirectories to look for regular expression matches; my regex requires negative lookbehind.

Perl has negative lookbehind, but as far as I can tell GNU grep doesn't support negative lookbehinds.

What's the easiest way to get an equivalent to GNU grep that supports negative lookbehinds?

(I guess I could write my own mini-grep in Perl, but that doesn't seem like it should be necessary. My copy of the Perl Cookbook includes source for tcgrep; is that what I should use? If so, where's the latest version? Don't tell me I have to type this entire program!)

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Dan Fabulich
  • 37,506
  • 41
  • 139
  • 175

2 Answers2

24

Use ack! Ack is written in Perl so it uses Perl's regex engine (by default).

The negative look-behind is ack "(?<!bad)boy" (per willert's comment)

chelmertz
  • 20,399
  • 5
  • 40
  • 46
too much php
  • 88,666
  • 34
  • 128
  • 138
  • 1
    I thought someone might suggest this, but I don't think ack uses negative lookbehind. For example, I created a temp file in a temp directory containing two lines: "goodboy" and "badboy" and then used the sample from Perl in a Nutshell: `ack "(?<!=bad)boy"` ... it returned both lines. If the regex were being followed, only the "goodboy" line should return. (I'll reverse my downvote if you turn out to be right after all.) – Dan Fabulich Mar 22 '10 at 04:34
  • 4
    The negative look-behind is ack "(?<!bad)boy", get away with the = – willert Mar 22 '10 at 04:39
  • WTF? "Vote too old to be changed, unless this answer is edited." @too much php, make an edit and I'll fix it, sorry. :-( – Dan Fabulich Mar 22 '10 at 04:48
  • `!` in `ack "(?<!bad)boy"` will be intercepted by bash (`bash: !bad: event not found`), use single quotes `ack '(?<!bad)boy'` –  Jul 30 '14 at 10:10
3

Thanks to a comment from other question. I've found that negative lookbehind is experimentally supported in grep with the -P/--perl-regexp option, so you may still not need to use a different tool if you prefer to keep using grep.

By the way, my preferred alternative to grep is grin (which is written in python).

Community
  • 1
  • 1
jcollado
  • 39,419
  • 8
  • 102
  • 133