I do a lot of things by command line. Still. It’s faster, it’s easier, and in many cases, gives me more control. And as I always mention, people who use command line are people who really lazy. We don’t like sixteen clicks. If we can copy/paste and change one thing, we’re happy.

For ages, when I wanted to search my local repository of plugins, I’d whip out something like this:

grep -R "base64" ~/Development/WP-Plugin-Dir/* > ~/Development/WP-Plugin-Greps/base64-grep.txt

This works, but it’s slow and it’s not very pretty. The file output is a mess and it’s painstaking to sort through and understand.

/home/me/Development/WP-Plugin-Dir/jetpack/class.jetpack-post-images.php:                ob_start(); // The slideshow shortcode handler calls wp_print_scripts and wp_print_styles... not too happy about that
/home/me/Development/WP-Plugin-Dir/jetpack/modules/comments/comments.php:                ob_start();
/home/me/Development/WP-Plugin-Dir/jetpack/modules/contact-form/grunion-contact-form.php:                ob_start();
/home/me/Development/WP-Plugin-Dir/jetpack/modules/custom-css/custom-css.php:            ob_start('safecss_buffer');
/home/me/Development/WP-Plugin-Dir/jetpack/jetpack.php:                  ob_start();
/home/me/Development/WP-Plugin-Dir/jetpack/jetpack.php:          ob_start();

On the other hand, there’s this:

ack --php 'ob_start' ~/Development/WP-Plugin-Dir/ > ~/obstart.txt

That actually gives a rather similar output:

/home/me/Development/WP-Plugin-Dir/jetpack/class.jetpack-post-images.php:36:               ob_start(); // The slideshow shortcode handler calls wp_print_scripts and wp_print_styles... not too happy about that
/home/me/Development/WP-Plugin-Dir/jetpack/modules/comments/comments.php:138:              ob_start();
/home/me/Development/WP-Plugin-Dir/jetpack/modules/contact-form/grunion-contact-form.php:264:              ob_start();
/home/me/Development/WP-Plugin-Dir/jetpack/modules/custom-css/custom-css.php:350:          ob_start('safecss_buffer');
/home/me/Development/WP-Plugin-Dir/jetpack/jetpack.php:872:                        ob_start();
/home/me/Development/WP-Plugin-Dir/jetpack/jetpack.php:928:                ob_start();

That’s ack, which claims to be better than grep, and I’m kind of agreeing. Let’s look at the small differences.

  • Line numbers. That will help me find the code later.
  • Only searching PHP files
  • Recursive by default
  • Ignores SVN and other similar folders.

How do you do only PHP files in grep?

grep pattern $(find . -name '*.php' -or  -name '*.phpt' -or  -name '*.php3' -or  -name '*.php4' -or  -name '*.php5' -or  -name '*.phtml' )

Right. Like I’m going to remember that.

And we can make ack better. Let’s ignore a folder:

ack --ignore-dir=akismet 'string'

How about customizing my output so I can check how often a plugin is doing_it_wrong()?

ack --php --group 'ob_start' ~/Development/WP-Plugin-Dir/ > ~/obstart.txt

That’s a little easier to read.

350:            ob_start('safecss_buffer');

872:                    ob_start();
928:            ob_start();

Just want a list of the filenames?

ack --php -l 'ob_start' ~/Development/WP-Plugin-Dir/ > ~/obstart.txt

Or what if I want to search all instances of ob_start() in jetpack/jetpack.php? You can make ack sit up and beg.

You can see that ack is a lot more powerful right away when it comes to being able to quickly use the data without a lot of parsing. There are some catches with ack, though, like it has a whitelist of file types that it will search, so if you don’t tell it to search .html, it won’t. That’s a small price to pay for me.

The documentation is written in nerd, so I generally find looking at concrete examples is more helpful. Do you have tricks with ack (or even grep) that save you time and money?

Reader Interactions


  1. I learned grep before ack and I’m still more comfortable with it. Not that ack doesn’t have some advantages, but some that you mention grep can actually do. For example, -n adds line numbers, --exclude-dir=akismet will ignore a directory, -l will list just the files. For checking only php files, --include=*.php* will check in .php files as well as .php3, .php4, .php5, and .phpt. You’ll have to also add --include=*.phtml to add that extension, or alternatively just use *.ph*.

    I don’t use abnormal php file extensions, so my usual grep command is something like:
    grep -inR --color --include=*.php thing_to_find

    I actually alias that to grepphp (and to grephp since I often seem to miss type that) so I just do this:
    grepphp thing_to_find

    You could instead just use this:
    grep -inR --color --include=*.php thing_to_find

    I don’t know of any equivalent to –group though, which looks pretty nice!

  2. Great post Mika. I use ack all the time when working with the WordPress codebase. I sometimes use it more than the codex. For example, if I want to use an escape function but I don’t remember all of them, I can google “data validation” and open the Codex article on Data Validation. Or, I can just:

    ack ‘function esc_’

    Through the WordPress codebase, which is easier, faster, and will never be outdated. I started using ack earlier this year, after Daniel’s talk about The Zen of WordPress Development at WordCamp Phoenix. I then also ditched TextMate in favor of Sublime.

    My brother Gennady also published a related article called ack-grep vs grep.

    Just my two cents,

    • I didn’t realize that article was your brother! I read it a couple weeks ago while thinking about this post 😀

      I’ve been trying to simplify a lot of things in code, and mastering classes and just using WP instead of reinventing the wheel (I’d love to re-write a plugin of mine, but that becomes complicated doesn’t it?) For coding, I like Coda. I tried TextMate and Sublime but never got a feel for them. That said, I know a lot of software is comfort, and if I don’t like an app, I won’t use it.

      Putting everything in Coda, Git and SVN (which is another post), I managed to get my process a little faster. Though I still will code in GitHub, and then commandline my SVN because I can do that faster 😉

%d bloggers like this: