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

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Ryan Rauh

My name is Ryan Rauh and I like shiny things. If I've seen it on twitter more the twice most likely I've looked at it or tried it. I really like memes and other silly and seemingly useless things out on the internet. I blog about things *I* think are cool and interesting, I hope you will find them cool and interesting too.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Anonymous

    Uh….yeah… ;)

    • Anonymous

      Totally dig the layout – its a nice perspective on blogging.

      • Anonymous

        Thank you?

        • Anonymous

          Compliments – it’s like a story line, super fun to read. As compared to most blogs that just present information.

          • Anonymous

            Thanks! I didn’t know if that would annoy some people

  • http://ole.tange.dk/ Ole

    I assume you ignore paths with space because of The Separator Problem (pi.dk/5). Consider using GNU Parallel to get that to work.

    • Anonymous

      The *correct* way is to use -print0

      ~> find . -type f -print0 | xargs -0 grep dovetail
      That says, print the output using 0 (-print0) as the delimiter and pipe that into xargs setting the delimiter to 0 (-0)