The *nix Rube Goldberg Machine – find/grep/vim


Learn your shell!

Piping grep into grep

Yo Dawg

I was spelunking my .bash_history and came across this little piece of awesome.

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.* | grep dovetail | grep -v .*\.css | grep -v dovetail\/dovetail | cut -d \: -f 1 | xargs gvim

Wow! So what the heck was I doing there? Lets walk through it.

So I’ve got a problem… I am OCD about where asset files are located in our project. It’s a complete mess and every time I complain about it…

“It will be too hard to go through the app and change all the paths…”

guise... srsly

“You under estimate my command line awesome-itude!”

Turns out its not that hard of a problem, let me break it down. All of our asset imports are abstracted out into an extension method we call from our view

<% this.Asset("myasset"); %>

Perfect so I have something consistent to grep for

~/lecode> find source/ -type f

Find all the files in the source directory

~/lecode> find source/ -type f | grep -v " "

Pipe that into grep and inverse match any path with a space (-v)

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.*

xargs that path into grep and search each file for any lines containing `this.Asset*`

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.* | grep dovetail

I only care about asset calls that contain dovetail

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.* | grep dovetail | grep -v .*\.css

Inverse grep (-v) any lines containing .css

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.* | grep dovetail | grep -v .*\.css | grep -v dovetail\/dovetail

console output

Inverse grep (-v) assets that start with dovetail/dovetail because those are correct.

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.* | grep dovetail | grep -v .*\.css | grep -v dovetail\/dovetail | cut -d \: -f 1

Notice how grep outputs the file path and then the match. We can use cut to parse the output on the “:” (-d :) and take the first column (-f 1)

console output

~/lecode> find source/ -type f | grep -v " " | xargs grep this\.Asset.* | grep dovetail | grep -v .*\.css | grep -v dovetail\/dovetail | cut -d \: -f 1 | xargs gvim

Now I have my file names, xargs that into gvim and it loads up a new instance of gvim with all the files I need to change in a buffer list. Now I can make my change and :bnext (buffer next) to the next file.

“It looks like you are trying to change a bunch of files… Want to use find and replace?”

“Shut up troll!”

Deeerp

-Ryan

The *nix Rube Goldberg Machine