09 March 2008

Ack is my favorite new tool

Ack is my favorite new tool. I highly recommend it. It is even written in my favorite programming language -- you know, the one with the really supercharged and usable regexp library.

Over the years, I have written some handy tools in this area....like for example, my "txtfind" shell alias:

 
   # put this in your .bashrc/.kshrc/etc.
  txtfind () {
    if [ $# -eq 0 ] ; then
       txtfind .
    else
       perl -MFile::Find -e 'find(sub{ print "$File::Find::name\n" if (-f && -T); }, @ARGV);' "${@}"
    fi
  }


This alias takes an (optional) list of directory names and searches underneath them -- when a "text" file is found, the filename is printed. To a shell hacker like me, it is very common to type things like:
txtfind /etc | xargs grep 192.168.9.37
...if, for example, I wanted to figure out why a machine was configured to use some strange IP address. This beats typing something like:
find /etc -type f -print | xargs grep 192.168.9.37
...because, of course, this will likely cause grep to troll through some binary files. In the end, this might hose your terminal.

I even have shell aliases like "binfind" and "dostxtfind". I have another alias called txtfind0 that allows me to use it in this manner:
txtfind0 /usr | xargs -0 grep foo
...but with this new tool, ack, I'll be able to eliminate a lot of hassle by simply typing something like:
ack --type=text foo /usr
That's not to say that things like my txtfind0 alias are now obsolete. Let's say, for example, I wanted to find a file that contained both the phrases "weapons of" and "mass destruction" -- in this case it would be as easy as:
txtfind0 /usr/secret | \
xargs -0 perl -l -0777 -ne 'print $ARGV
if (/weapons of/i && /mass destruction/i)'
But, just the same, I am enthusiastic to have a great new tool in my arsenal. Ack has a bunch of other features that I haven't really touched on here (my favorite is its intelligent ability to skip files in .svn directories) -- I encourage everybody to check ack out.