17.01.09

ack-grep - a source-aware grep replacement (searching for content in files)

Link: http://petdance.com/ack/

ack (or ack-grep) is a nice "grep" replacement, when searching in a directory with source files.

It does not require any path to start searching and the recursive option is enabled by default. Also, it will exclude directories of version control systems (like .svn, CVS, .bzr, .git) and nicely formats hits.

E.g., "ack-grep foo" will search all (relevant) files in the current directory for "foo". And if the current directory is under source control, it will be much faster than using "grep -R foo .", since it excludes the control directories. (Ye

I haven't tinkered with its options or man page, although I'm using it since quite some time now, since the defaults are so good already and it provides a great out-of-box experience and performance boost.

The man page states when to use the "normal" grep:

WHEN TO USE GREP
ack-grep trumps grep as an everyday tool 99% of the time, but don’t throw grep away, because there are times you’ll still need it.
E.g., searching through huge files looking for regexes that can be expressed with grep syntax should be quicker with grep.

Additionally, "grep" appears to be still more useful when chaining commands, e.g. to find all references of "css" in the file list of "ack-grep" ("dpkg -L ack-grep | xargs grep css"). When using ack-grep here, it will also recursively search in all listed directories (as in "for i in $(dpkg -L ack-grep); do test -d $i && echo $i; done").

On Debian/Ubuntu, ack-grep is only a "sudo apt-get install ack-grep" away.. :)

(The ack homepage has some convincing Testimonials, too)

By Daniel in Open Source, Ubuntu, musthaves, Debian2009-01-17 English (EU) Email

8 comments

Comment from: Bryan Forbes [Visitor]
Bryan ForbesIf you're looking for something similar that's a bit more pythonic and has a bit simpler command line options, try out grin: http://pypi.python.org/pypi/grin

My favorite feature is searching in specific file types: grin -I*.js connect. I know ack can do this, but I could never remember the --type flags for it. The other cool thing is that the output of grin is colored and highlights where in the line the pattern shows up.
2009-01-17 @ 07:31
Comment from: foobar [Visitor]
foobarack highlights hits, too
2009-01-17 @ 11:31
Comment from: Tblue [Visitor]
TblueCool, thanks.
2009-01-23 @ 15:23
Comment from: Benoit Caccinolo [Visitor]
Benoit CaccinoloAck-grep saved my life several times. I'm using it a lot now on iPhone development:

http://bcaccinolo.wordpress.com/2010/09/28/killer-tool-to-develop-on-iphone-ack-grep/
2010-09-28 @ 12:33
Comment from: Jonathan Hartley [Visitor] Email
Jonathan HartleyI'm really puzzled why people prefer 'ack' over 'grep'. It doesn't seem to provide anything that grep doesn't. Of the listed 'reasons to prefer ack' on it's homepage, almost all of them are false or misleading or undesirable.

grep will also recurse into directories ('-r'), and it will highlight hits ('--color'). It will skip source control directories ('--exclude-dir=\.git')

ack is advertised to be faster, but it is only faster because it skips searching a bunch of files. If you configure grep to skip source control, as above, and skip binary files ('-I'), then ack is actually slower than grep.

It's true that grep needs configuring to make it behave the way you want. So instead of installing 'ack', create an executable on your path to select the default options you want grep to use. Mine looks like:

$ cat `which grp`
#!/usr/bin/env bash
grep -rI --color --exclude-dir=\.bzr --exclude-dir=\.git --exclude-dir=\.hg --exclude-dir=\.svn --exclude-dir=build --exclude-dir=dist --exclude=tags $*

I did this once in the 1980s, and grep has been fine for me ever since.

The whole 'ack' project is a massive waste of time - throwing away decades of bugfixes, optimisations, and a community of knowledge, for no reason at all.
2011-10-04 @ 11:23
Comment from: Markus [Visitor]
MarkusJonathan, you said it yourself, by default grep is not good enough. You need to know the magic arguments that do the right thing. Why should every single user go to fix the tool instead of picking one that works?
2012-03-09 @ 13:39
Comment from: Andy Lester [Visitor] Email
Andy LesterYour assertion that ack is a "massive waste of time" is untrue. It's been very beneficial and has saved countless users countless hours of time.

The premise of "for no reason at all" is also untrue. You may not agree with the reasons, but the reasons do indeed exist.

Nobody says that grep can't recurse or colorize or skip directories. The difference is that ack does those things out of the box without having to customize it. For old Unix hands like us, that's not a problem. For others, it is.
2012-03-13 @ 18:14
Comment from: TK [Visitor]
TKIMO Jonathan is right: If ack-grep does the same thing as find / grep with given arguments, then ack-grep should instead be rewritten as a mere wrapper around find / grep to just provide better defaults. The mere need for better defaults does not justify writing a tool from scratch. That would be like a car company designing a new car from scratch because some users prefer different door handles. Two tools doing the same just means twice the maintenance effort for the community.

ack-grep is a waste of time compared to the imaginary alternative of having written such a mere lightweight easy-to-maintain grep wrapper which would have benefited the same users the same amount of time.

As to speed, for me, this
find . -name "*.[ch]*" ! -regex ".*[/]\..+[/]?.*" -print0 | xargs -0 -n1000 grep -IHn something
seems to often run faster than
ack-grep --cpp something
when searching in cpp files.

Same for dropping --cpp and -name "*.[ch]*". This on Ubuntu Lucid on a Core i7, measured using GNU time.
That command can be aliased, or wrapped by a small script in any scripting language to provide the ack options for language specific file extentions, without reinventing the wheel. (Note for me it often runs much faster when run twice, even with different keywords some caching going on somewhere, which is lost on ack).

As alias (put into your ~/.alias in Linux):
alias ag='find . ! -regex ".*[/]\..+[/]?.*" -print0 | xargs -0 -n1000 grep -IHn'

Also the command example I give does not hide unusual extentions that the user did not know were excluded from ack.

Also note the rather new parallel command for such optimisation on multi-cores: http://www.gnu.org/software/parallel/man.html#example__parallel_grep which can make the find / parallel/ grep combo much faster than ack (xargs does not do well for parallel output, see http://www.gnu.org/software/parallel/man.html#differences_between_xargs_and_gnu_parallel)
2012-04-10 @ 06:13

Leave a comment


Your email address will not be revealed on this site.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)
This is a captcha-picture. It is used to prevent mass-access by robots.
Please enter the characters from the image above. (case insensitive)
You can just use your OpenID to provide your name, e-mail and url.
Seitenleiste