rak, ack and findit
on December 13, 2007 @ 04:52 AM
In Helpful Command Line Tools from last month I posted on my custom findit script.
Jason Porrit commented on that post and mentioned ack , a perl alternative to grep and find which offers terminal color highlighting to your results. I also found this morning a ruby alternative called rak
All of these utilities do the same thing, they search a directory structure for files whose contents match a given pattern.
Here’s Ack

Here’s Rak

Here’s findit

Overall ack and rak beat out findit, but findit has a much better name. I think I’ll just alias findit to rak. (yes I”m biased to ruby code over perl code).
The only thing ack and rak are missing is a filename only option. If I can find every file matching a pattern from a given start directory that would rid me of findfile as well!
Helpful Command Line Tools
on November 23, 2007 @ 02:54 PM
Here’s a post about some of the command line tools (both standard on *nix systems and homegrown) which make software development just a little more efficient.
The homegrown tools may only work on OSX. This is because unix utilities on OSX often have different options to do the same thing (such as sed’s -E on OSX and -r in Ubuntu).
find
find is a unix utility for searching files in a directory hierarchy. find is a powerful tool that comes with a lot of options. Some are more common then others.
Here are the options I use frequently:
- -name pattern – this will match filenames against the supplied pattern
- -exec command argument \; – runs the specified command against each file matched
1 2 3 4 5 |
# Using -name to find all files or directories which match the pattern "*.rhtml"
find ./ -name "*.rhtml"
# Using -exec to find all rhtml files whose file contents match "Continuous Thinking"
find ./ -name "*.rhtml" -exec grep -Hn "Continuous Thinking" {} \; |
For development the -name option doesn’t help me much as TextMate’s Apple-Tab is far superior and faster to use, but editors like TextMate lack the efficiency of doing a -name and -exec combination from the command line. Sure TextMate has Apple-Shift-F to search file contents project wide, but what about all of those files you want to exclude (like log files), plugins (vendor/plugins) or the whole rails directory (vendor/rails).
TextMate doees give you the ability to exclude certain files (or directories) from your TextMate project, but it removes all references to them from within your TextMate project. This feature will speed up Apple-Shift-F searches, but sometimes you want to include those other files or directories.
The find command given the -name and -exec options can be a pain to type out. So I’ve written a helper script called findit.
findit
findit is a wrapper around find. It’s simple and fast. It’s usage is simple:
- findit where pattern
Maybe you’re looking for that view template which contains the text ‘Fuzzy Bear’:
1 2 |
zdennis@elijah:> findit app/views/ Fuzzy Bear app/views//bears/new.rhtml:26: <label for="fuzzy_bear">Fuzzy Bear</label> |
Notice how you don’t have to use quotations around the arguments Fuzzy Bear. Everything after the first argument is treated as a part of the pattern.
Another example may be that you’re looking for where alias_method_chain is defined in rails. Well let’s look:
1 2 |
zdennis@elijah:> findit vendor/rails/ def alias_method_chain vendor/rails//activesupport/lib/active_support/core_ext/module/aliasing.rb:23: def alias_method_chain(target, feature) |
So the power of findit comes from the fact that it’s easy to use and it handles most common occurrences of what a developer like me looks for such as the filenames that matched, the line numbers it matched on and a printout of those matching lines.
findit also ignores all .svn, CVS, .log, .project, .dylib and .o files. Of course you can change this though by editing the findit.
Download
Give it a try click here
findfile
findfile is similar to findit except that it only matches on filename patterns. The usage is still the same:
- findfile where pattern
Recently I had some issues with installing PostgreSQL from ports and there was a patch to the Portfile for the PostgreSQL port to get it to install correctly. I had no idea where the Portfile was so I let findfile to the work:
findfile /opt/local/var/macports Portfile | grep -i postgres |
Download
Give it a try click here
locate | slocate
locate (and by extension slocate) may be one of the most under utilized unix tools in the mac world.
locate is used to find files by searching a database. Since it uses a database of file paths it is almost instantaneous whereas tools like find can take a while depending on how much files you have in a directory structure.
slocate can be thought of as “secure locate”. For more information consult this doc
Here’s the same example from findfile but this time using locate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
locate Portfile | grep postgres /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql7/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql80/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql80-doc/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql80-server/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql81/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql81-doc/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql81-server/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql82/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql82-doc/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql82-server/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql83/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql83-doc/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql83-server/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql_autodoc/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/java/postgresql-jdbc/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/python/py-postgresql-exception/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/python/py-postgresql-greentrunk/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/python/py-postgresql-layout/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/python/py-postgresql-pqueue/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/python/py-postgresql-proboscis/Portfile /opt/local/var/macports/sources/rsync.macports.org/release/ports/ruby/rb-postgres/Portfile |
locate loses its usefulness when it’s database is out of date. Fortunately it’s easy to add it to cron. Here’s what I have in my /etc/crontab file to have slocate update it’s database every night at midnight:
0 0 * * * root /opt/local/bin/slocate -u |
locate comes with Leopard, and slocate comes with ports. I have my locate aliased to actually run slocate. They use different databases so pick one and use it or alias one command over the other like I have. There’s not much of a point to have both slocate and locate.
If you decide to give slocate a try you can install easily by running:
sudo port install slocate |
whatsmyip
whatsmyip is a script I use in my screen configuration so I can always tell what my local ip address is. ifconfig output is pain enough to look at and I try to avoid it at all costs:
1 2 |
zdennis@elijah:> whatsmyip en1: 10.0.4.100 en2: 10.37.129.2 en3: 10.211.55.2 |
Download
Give it a shot, click here
OSX Leopard mysql gem for ruby
on November 21, 2007 @ 10:12 AM
If you install mysql from ports then you can install the mysql ruby bindings in the following manner:
1 2 3 4 5 |
sudo su ARCHFLAGS='-arch i386' gem install -r mysql -- \ --with-mysql-include=/opt/local/include/mysql5/mysql/ \ --with-mysql-lib=/opt/local/lib/mysql5/mysql/ |
If you don’t use ports then check out http://nullcreations.net/entry/installing-ruby-mysql-gem-in-osx-10-5-leopard
OSX Leopard sqlite-ruby and sqlite2
on November 18, 2007 @ 12:07 PM
OSX Leopard comes with sqlite3 and sqlite3-ruby pre-installed. If you need to install the sqlite-ruby gem for sqlite2 you’ll find that it fails to install by itself.
Here’s what you’ll probably get:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
zdennis@elijah:>sudo gem install sqlite-ruby
Select which gem to install for your platform (universal-darwin9.0)
1. sqlite-ruby 2.2.3 (ruby)
2. sqlite-ruby 2.2.3 (mswin32)
3. sqlite-ruby 2.2.2 (ruby)
4. sqlite-ruby 2.2.2 (mswin32)
5. Skip this gem
6. Cancel installation
> 1
Building native extensions. This could take a while...
ERROR: While executing gem ... (Gem::Installer::ExtensionBuildError)
ERROR: Failed to build gem native extension.
ruby extconf.rb install sqlite-ruby
checking for main() in -lsqlite... no
checking for sqlite.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
--with-sqlite-dir
--without-sqlite-dir
--with-sqlite-include
--without-sqlite-include=${sqlite-dir}/include
--with-sqlite-lib
--without-sqlite-lib=${sqlite-dir}/lib
--with-sqlitelib
--without-sqlitelib
Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/sqlite-ruby-2.2.3 for inspection.
Results logged to /Library/Ruby/Gems/1.8/gems/sqlite-ruby-2.2.3/ext/gem_make.out |
If you become root and attempt to do the install it will also fail.
Installing with sqlite2 from ports
I have MacPorts installed and you’ll want to make sure sqlite2 is installed:
zdennis@elijah: sudo port install sqlite2 |
Now to install sqlite-ruby:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# run the command as root zdennis@elijah: sudo su sh-3.2# ARCHFLAGS="-arch i386" gem install sqlite-ruby -- --with-sqlite-include=/opt/local/include/ --with-sqlite-lib=/opt/local/lib/ Select which gem to install for your platform (universal-darwin9.0) 1. sqlite-ruby 2.2.3 (ruby) 2. sqlite-ruby 2.2.3 (mswin32) 3. sqlite-ruby 2.2.2 (ruby) 4. sqlite-ruby 2.2.2 (mswin32) 5. Skip this gem 6. Cancel installation > 1 Building native extensions. This could take a while... Successfully installed sqlite-ruby-2.2.3 Installing ri documentation for sqlite-ruby-2.2.3... Installing RDoc documentation for sqlite-ruby-2.2.3... |
That’s it. Now it works:
1 2 3 4 5 6 |
zdennis@elijah: irb irb(main):001:0> require 'rubygems' => false irb(main):002:0> require 'sqlite' => true irb(main):003:0> |
So I Got A Mac
on February 20, 2007 @ 05:49 AM
So I got Mac. A second-tier Mac Book Pro actually. After the past few years of being a dedicated linux enthusiast, it appears to be the best bet out there for a dual business/development box.
(I’ll still run Kubuntu for my desktop box at home and Ubuntu server for my server, but as of right now I’m not having any second guesses about the Mac. )
The built-in webcam and the iChat video support immediately made it worth it. I got Emacs working in just a few minutes and firefox is downloaded and installed.
I spent a few hours today installing/compiling a bunch of packages from MacPorts, but so far it’s been well worth it.
I am digging the magnetic power adapter as well. Thanks to Brandon, John and Craig for letting me pick their brains about OSX throughout the day!

