(Prepared to be shared at my work )
Through long trial and error, and with a healthy dose of help from the Linux from Scratch website, I've accumulated some good knowledge of Bash in my time with Linux and OS/X. Here are the highlights:
When I first got a Mac, I was frustrated by needing to interact with the point and click GUI all the time. My thesis advisor, Dan Lizotte, told me "But no, you need to think like a Mac user!". That's when he told me about two tricks. The first is pretty cool: open a terminal, type "cd ", and then drag and drop a folder from the Finder into your Terminal window. The path gets pasted in, and when you hit Enter you'll be sent to that folder!
The reverse is even more powerful:
open . # open the current directory in Finder open song.mp3 # open the file with the normal program # OSX would associate with that file open -a VLC.app song.mp3 # open the file with a specific app!
Another great command that comes in useful all the time is sed. Here are some useful commands
echo "this is a test" | sed -e 's/test/sed test/' # outputs "this is a sed test" sed -i'' -e 's/test/sed test/' file.txt # replace words in a file in place sed -i '' -e 's/test/sed test/' file.txt # OS/X version of the above command
You'll need to use man regex to harness the full power of sed's replacements.
Grep is great, and really useful
grep "search string" file cat file | grep "search string" grep -v "inverted search" file grep -r "line of code" somefolder # search a directory recursively grep -r "line of code" * grep -rl "line of code" * # only output the filenames grep -v '^#' file # -v inverts the match - this shows all lines NOT starting with # grep -C 3 string file # show the line plus the three lines before and after it grep -A 2 -B 4 string file # show the line plus 2 lines after and 4 lines before grep -m 3 string file # show a maximum of 3 matches
Often I have great success combining grep and sed to do incredible things when processing output. Another command that comes in handy when modifying files and streams is awk. The only command I ever really use with awk is this:
echo "one two three four five" | awk '{print $1 $5}' # outputs "one five" echo "one,two,three,four,five" | awk -f, '{print $1 $5}' # outputs "one five" by splitting on comma instead of space
Head and tail are also very useful:
head file # show ten lines tail file # show last ten lines tail -n+10 # show all but the last ten lines head -n3 file # show first three lines tail -n3 file # show last three lines
But I find my most productivity comes from the Bash-specific tricks. Bash is interesting; to get information on its built-in commands, you need to use "help command" instead of "man command", so a lot of them are kind of esoteric.
My favourite by far is history.
history # output a numbered list of all your recent commands !1000 # execute command 1000 from the history with the same arguments !1000:p # show command 1000, and let you hit the Up arrow key to modify and/or run the command rspec cool_spec.rb vim !$ # !$ is replaced by the last argument of the previous command rspec !$ # so these two commands edit and then re-run rspec on cool_spec.rb !! # re-run the previous command sudo !! # re-run the previous command via sudo grep -rl string * # get list of files containing the string vim $(!!) # edit the list of files you just found with grep # $() runs a command and returns the output as arguments !rs # finds the most recent command in history starting with "rs" and runs it
You can also use "reverse-i-search" to search through your history a bit more efficiently than with !?. Just type Ctrl+R and then start typing the command you want. This is useful for instance if you want to re-run a command prefixed with sudo, because it's harder to match. ! only matches on the first word.