The *nix Rube Goldberg Machine!
Learn your shell!
Since I’ve started at Dovetail in June the best tool I’ve sharpened is my command line skills. My first week at Dovetail we got a surprise visit from @bob_pace and while pairing with him I was amazed by how effective he was with the command line. Well that really motivated me to improve my own skills.
I’m gonna run through some basic building blocks that are required to work with files in the command line.
First step is finding the files you want to work with.
- List all the files in your pwd (present working directory). This will list every file and directory and recursively from the
path you have specified
~> find .
- List all files with certain extension
~> find . -name "*.js"
- List only files and not directories
~> find . -type f
- Protip: If you suspect files will spaces in the name (try to never do this!)
~> find . -type f -print0
xargs is your favorite buddy/friend/pal when working will large lists of files. The only thing xargs does, is take whats piped into it and stick it on the end of the next command.
Try it yourself
~> find . -name "*.js" | echo
Whoops… WTF, there is no output. Now try
~> find . -name "*.js" | xargs echo
See if put it at the end of the next piped command, simple right!?
ZOMG! grep has changed my life…
grep will search a line of input for with a regular expression that you provide it. If you pass it a file name it will search each line of the file and output any matches.
~> echo "hello" | grep hello
See simple right!
The command line is all about chaining inputs and outputs, its magical! Lets do that.
For example if you are using nuget and you want to know what version of FubuMVC you are using
~> find. -name "packages.config" | xargs grep -h FubuMVC\.References
Now lets talk about whats *really* awesome about the command line. MUTHA !@#$in sed! stands for stream editor and its amazing.
Back in the early days of using nuget, we got into a situation where it was adding multiple version of the same dependency in our package configs…. its was a pain in the ass! Mostly due to the fact we have 30 projects and a lot of them are bottles that are not loaded with the core products solution file. Well if you are using the Visual Studio nuget manager fail sauce POS it would get all messed up and start putting extra references in the package configs. When we switched to our own tool to manage this madness, ripple it got all sorts of messed up.
So sed to the rescue! So the great thing about the command line is that you can fine tune your command before you actually go through with it
~> find. -name "packages.config" | xargs grep -h FubuMVC\.References | sed d
Bam that should return no output, you are telling sed to delete any line that is passed to it. Now lets say that all of your project have two references to Fubu 0.9.2.722 and 0.9.3.731 and you want to delete the lower one. Lets practice first.
~> find. -name "packages.config" | xargs grep -h FubuMVC\.References | sed /FubuMVC\.Reference\..*722/d
That should only output the higher version of the two versions. Now that we know it works… we can put it all together and get destructive. We will just tweek our current command a little. Switch the grep flag to -l (lower case L), this will tell grep to output the filename only. Then we’ll need to pipe this to sed, but we’ll need to xargs it to the end since we want sed to modify the file. Then we’ll need to tell sed to delete the lines that contain the lower version number passing the flag -i will tell sed to modify the file in place.
~> find. -name "packages.config" | xargs grep -l FubuMVC\.References | xargs sed -i /FubuMVC\.Reference\..*722/d
Bam! I just modified 30 files without opening any of them…. Like I said its the best thing I’ve learned my entire career!
Herp it don’t Derp it!