Shell Tricks: a random selection

[Tweet]

Quick tips are random posts regarding something I discovered on my way to something bigger. They usually get longer than “quick” would imply, for which I refuse to apologize.

It’s been a while since I posted any shell tricks, so I’m just dumping a few random but useful aliases out here…

From Terminal to Finder

First, a one-line function (Bash, but easily converted) for opening Finder, either to the path in the first argument or to the current directory. Due to the way the open command works, you can use relative paths from the current directory in the argument.

f() { open -a "Finder" "${1-.}"; }

Copy the Current Directory Path

A stupid easy alias for copying the current directory to the clipboard. Simple, but useful. Note that it trims the trailing newline from the result in the clipboard.

alias cpwd='pwd|tr -d "\n"|pbcopy'

Faster Command History Substitutions

Here’s one for fixing the last command with a simple substitution, no special syntax, so if the command you messed up was cat myfile.tst, you can run fix tst txt to find/replace “myfile.txt” to “myfile.txt” and execute the result. I find this easier than fc substitutions, and I’ve always found the Bash syntax ^tst^txt to be more difficult to type quickly.

Note that it will only replace the first match, not a global substitution. Just give it enough context to match the right part…

fix() {
	local cmd=$(fc -ln -1|sed -e 's/^ +//'|sed -e "s/$1/$2/")
	eval $cmd
}

Faster Git Conflict Resolution

Want to quickly merge git conflicts using --ours or --theirs? These aliases will check git status for lines starting with U (unmerged), passing listed files to xargs to run one of the git checkout commands.

alias gmine="git status|grep -e '^U'|sed -e 's/^UU *//'|xargs git checkout --ours"
alias gtheirs="git status|grep -e '^U'|sed -e 's/^UU *//'|xargs git checkout --theirs"

Bash History To Go

Lastly, when I’m working in a shell and want to open a new view into it from another Terminal (iTerm) window or tab, I usually want to carry my recent command history with me. It’s easy to do with the history command, writing to the $HISTFILE and then reading from it in a new session.

# share history between terminal sessions
# [h]istory [e]xport
alias he="history -a"
# [h]istory [i]mport
alias hi="history -n"

Bonus Bash/iTerm Tip

In Bash, you can use M-. (Option-period) to add the last argument of the previous command to the current command line. This is great, for example, after you’ve created a new directory and want to cd into it in the next command.

$ mkdir /path/to/new/dir
$ cd [M-.]

Wouldn’t it be great if there was a way to do that from the current command line, sourcing from preceding arguments? A keyboard command to repeat the last argument of the current command…

Bash history expansion shortcuts to the rescue. !# represents the current command, and you can add the :$ modifier to reference the last argument, so !#:$ repeats the argument I just typed. I have my shell set to expand ! shortcuts as soon as I hit space, so I can add this as a shortcut in iTerm and have it expand automatically.

Under Preferences->Keys->Key Bindings, just add a new binding with the action “Send Text” and set the text to !#:$ (with a trailing space). Assign it to a hotkey (mine is Shift-Option-period). Neat.

As a side note, the history expansions also have modifiers for removing extensions from filenames, or filenames from paths, so you can make really easy shortcuts in the same manner for repeating the argument in useful ways. For example, to expand the last filepath argument with the current extension removed, use !#:$:r.

That’s all, hopefully at least one of these will make a nice addition to your toolbox.

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.