Saturday, September 3, 2011

Better Than Grep

UPDATE: Also check out the_platinum_searcher, which runs even faster than ack.

I've been using ack instead of grep for about four years now and I'm still loving it. It has saved me countless time and energy searching through large code bases and miscellaneous files and directories. Everyone who has ever used grep knows how useful and necessary a tool it is, so anything that might potentially be better than it is certainly worth a try.

Description from ack's home page: ack is a tool like grep, designed for programmers with large trees of heterogeneous source code. ack is written purely in Perl, and takes advantage of the power of Perl's regular expressions.

So what exactly makes ack better than grep? The main thing for me is that it requires much less typing to do common powerful operations. It's designed to replace 99% of the uses of grep. It can help you avoid complex find/grep/xargs messes and the like.

On the very surface, the two commands print lines that match a pattern:

    $ grep rkulla /etc/passwd
    rkulla:x:1000:1000:Ryan Kulla,,,:/home/rkulla:/bin/bash
    $ ack rkulla /etc/passwd
    rkulla:x:1000:1000:Ryan Kulla,,,:/home/rkulla:/bin/bash

In order to get grep to print with colored output you need to add --color. Which you could just make a shell alias to do implicitly. Ack will show colors automatically.

Where ack really shines is that it searches recursively through directories by default, while ignoring .svn, .git, and other VCS directories. So instead of typing something silly like:

    $ grep foo $(find . -type f | grep -v '\.svn')

You could simply type this instead:

    $ ack foo

ack automatically ignores most of the crap you don't want to search, such as binary files.

Also, instead of typing shell globs like *.txt to search just text files, ack uses command line arguments such as --text. If you were to grep for 'foo' in *.txt, it would only consider files that ended with exactly .txt, whereas ack would consider .txt, .TXT. .text and even text files that don't have file extensions such as README. Conversely, you could type --notext to search for everything except text files. To see a list of the different file type arguments and which file types they affect type:

    $ ack --help=types
    --[no]html .htm .html .shtml .xhtml
    --[no]php .php .phpt .php3 .php4 .php5 .phtml
    --[no]ruby .rb .rhtml .rjs .rxml .erb .rake
    --[no]shell .sh .bash .csh .tcsh .ksh .zsh
    --[no]yaml .yaml .yml
    ...

This is obviously incredibly convenient for any user. It's especially convenient for someone like a System Administrator who may be tasked with searching through all the "Ruby" files on a system, yet he might not know all about all the different file extensions that Ruby might use. With ack, all he has to remember is --ruby.

Use -a to search all files.

Ack will also give you more readable output than grep. It places things onto newlines so you can more easily discern the file name, line number, and pattern matches.

Because ack is written in Perl, it can take advantage of some of the language's features, such as proper Perl Regular Expressions and literal quoting. You can use -Q or --literal with ack to quote literally, similar to q() in Perl. From the ack-grep man page:

    If you're searching for something with a regular expression metacharacter, most often a period in a filename or IP address, add the -Q to avoid false positives without all the backslashing.

    Use ack-grep to watch log files Here's one I used the other day to find trouble spots for a website visitor. The user had a problem loading troublesome.gif, so I took the access log and scanned it with ack-grep twice.

        $ ack-grep -Q aa.bb.cc.dd /path/to/access.log | ack-grep -Q -B5 troublesome.gif

    The first ack-grep finds only the lines in the Apache log for the given IP. The second finds the match on my troublesome GIF, and shows the previous five lines from the log in each case.


You can do a lot of other cool stuff with ack that I won't go into because if I haven't convinced you to use ack by now, I never will. Consult the documentation for ack-grep if you like what you see.

4 comments:

  1. Thanks for this article. I have installed ack using Chocolatey and am now using it with windows powershell. Is there some way where I can use ack to search for a list of items?

    ReplyDelete
  2. Thank you Ryan! How could I live without knowing about this? Really handy tool in the arsenal. Recommended.

    ReplyDelete
  3. Ryan;
    Thank you for the introduction to a new favorite tool!

    ReplyDelete
  4. Thanks for this article. I try ack in my machine ubuntu.It's so great.

    ReplyDelete

Followers