Grep's out of date? Full ACK!

Posted by | Comments (2) | Trackbacks (0)

grep is a handy tool and I use it every day. But sometimes I wish it had some more features. For instance full-featured Perl compatible regular expressions (PCRE) since the current implementation is not complete (and I think it will never be), automatic recursive search or exclusion of non-text files etc.

Here a tool called ack comes into play. It's a search tool and grep replacement written in Perl, which is able to do all these things. Guess what! This tool uses full-featured PCRE for searching directory trees recursively. But it does not just search all files it can get hold of but rather filters them depending on their extension and/or contents. That means it does not search shadow directories such as .svn or .git directories unless you tell it to do so. Also binary files or files with no or unknown extension are excluded by default. That means you can search VCS working copies or build directories in good conscience.

So, how does it work? Basically, there is no difference to grep in general usage. Just specify the command and the pattern (which is a PCRE not an unfunctional default grep regex, be aware of that!).

ack mypattern

That's it! ack will now search you current directory tree for mypattern but only include files with a known extension outside shadow directories. Which file types are known can be discovered with:

ack --help types

But of course you can also define your own types. Let's assume you are a developer working on the PHP project and you're in the team to develop PHP 6. As of the time I write this, ack does only search PHP files with the extension .php, .phpt, .php3, .php4, .php5 and .phtml, but not .php6. To be able to search .php6 files we need to define this extension first:

ack --type-add php=.php6 mypattern

Now you're able to search .php6 files as well. However, it's quite inconvenient to specify the types each time you call ack. Therefore you can create a file called .ackrc in your home directory. In this file you can set all parameters you want to be applied by default. In our example this file has to contain a line like this (mind the additional = !):

--type-add=php=.php6

When you now check the known file types with

ack --help types | ack php --nocolor

you should see the new file extension in the list.

Instead of just adding new file extensions to existing types you can of course also add completely new types or redefine existing ones. For this use --type-set instead of --type-add.

Thanks to the file type feature, ack also allows searching for just a specific type of file. For example to search C and C++ files only, enter:

ack --type cc --type cpp searchpattern

To exclude specific file types just add a no at the beginning of the file type name.

But what if you have a directory, which includes many files without extension or with lots of extensions not known by ack? Just use the parameter -a. This will search all files regardless of their type but still exclude shadow directories. To include these as well, use -u.

More features!

These are the basics, but ack can do more. One handy feature, e.g., is to specify a pattern for a path. This enables you to select files based on a pattern instead of specifying the concrete names. You can do this by using the command -G pattern.

ack -G pathpattern searchpattern

Only files whose paths match the pattern pathpattern are included in the search. pathpattern is a PCRE which matches the whole path to the file relative to the current working directory.

Obviously, there are lots of other features and I recommend you read the man page (man ack) but I want to show you one more feature, which makes ack really easy to use in some cases. Have you ever struggled with searching the same set of files with different search terms? After performing the first search, you tap the up arrow key to repeat the last command and then hit the left arrow key many times to set the cursor to the position of the search pattern which is defined as the first parameter. This is very time consuming. Of course you can use the search and replace functionality of your shell history, but also that is not very convenient. What if you could specify the pattern as the last parameter? Well, with ack you can. Just use the --match command.

ack file1 file2 file3 --match searchpattern

Now you only have to tap backspace a few times to delete the old pattern and write the new one. No need to go to the beginning of the command line anymore.

Install ack

ack is not included by default in most distributions. To install it, either install the CPAN module App::Ack or use your package manager. Don't try to search your repository for ack. You'll get a lot of unrelated packages. Just install the package ack or ack-grep (the naming depends on your distribution).

To get more information about this handy tool, read the man page or visit the developers' website on betterthangrep.com.

I hope you enjoy it as much as I do. Surely, in some situations grep is still superior (e.g. when it comes to searching a very large amount of files where performance really matters) but in most cases ack is the way to go. I don't want to miss it anymore because it is really better than grep. smile

Trackbacks

No Trackbacks for this entry.

Comments

There have been 2 comments submitted yet. Add one as well!
tr
tr wrote on : (permalink)
Also check out ag - The Silver Searcher, faster ack.
Janek Bevendorff
Janek Bevendorff wrote on : (permalink)
You mean "this":https://github.com/ggreer/the_silver_searcher? That one looks indeed interesting. Wasn't aware of it. Thanks.

Write a comment:

E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

By submitting a comment, you agree to our privacy policy.

Design and Code Copyright © 2010-2025 Janek Bevendorff Content on this site is published under the terms of the GNU Free Documentation License (GFDL). You may redistribute content only in compliance with these terms.