Grepping with Ruby

What you knew: how to filter by pattern using grep on the command-line.

$ grep 'require' mycode.rb
> require "net/http"
> require "uri"
> ...

What you might not have known: the -n flag for the ruby interpreter.

$ ruby -ne 'print if $_ =~ /^require/' mycode.rb

The ‘n’ flag wraps the one-liner in a while gets loop druring which the current line is available through $_, and print with no arguments outputs the contents of $_. There is also the p flag:

$ ruby -pe '$_.upcase!' mycode.rb

The p flag is similar to n, but it always prints the contents of $_ after you’ve processed a line. With Ruby we have the power of our well-known regexp engine and string manipulation methods, so for a ruby person this is a win over grep + cut, sed and whatnot.

Of course, all these examples work with standard input instead of having a file specified in argument list.

What you most probably never knew: a regex literal in a condition is automatically matched against $_.

$ ruby -ne 'puts $1 if /^\s* def \s+ ([\w.]+)/x' mycode.rb

This only matches ruby method definitions and outputs the name of the method. Notice how the regexp stands on its own, but still evaluates to true only on matching lines.

Another example is grabbing the GitHub timeline feed and generating a summary of event types:

$ curl -s http://github.com/timeline.atom | \
  ruby -ne 'puts $1 if /:(\w+)Event\//' | sort | uniq -c

After searching, I’ve found reference to this in “Programming Ruby” book, section “Boolean expressions”. It was also noted that support for this functionality is, together with implicit $_ in many Kernel methods, slowly being phased out in Ruby 1.9. Such a shame.

For a historical look on more Perl-inspired (and, in turn, AWK-inspired) goodness in Ruby, read Ryan Tomayko’s excellent AWK-ward Ruby.