History Expansion
http://www.eriwen.com/bash/effective-shorthand/
http://www.catonmat.net/blog/the-definitive-guide-to-bash-command-line-history/
Bash One-Liners Explained, Part IV: Working with history - good coders code, great coders reuse
zshexpn: zsh expansion and substitution - man page
bash: History_Expansion - man page
Bang Bang - Command Recall in Linux
Unix history and bang commands — Jack Hsu
TODO: add zsh manual
man history
Each line of history is a command, consisting of more than one words (0-indexed).
cp myfile.txt my/directory/path
cd !$ # cd my/directory/path
vi /etc/fstabs # oops!
sudo !! # sudo vi /etc/fstab
echo 1 2 3 4 5 6 7 8 9 10 # test word designators
/path/to/file/a.b.c # test modifiers
echo $_ # last argument of last command
Event designators:
! start a history substitution, will use last command if no event designator specified
!! expands to the last command
!42 expands to the 42nd command in the history list
!-3 3 commands before (all arguments)
!string most recent command stating with string
!?string? most recent command stating with string
^foo^bar last command with the first occurrence of foo replaced with bar
!# expands to current command typed so far
Word Designators:
Word designators follow event designators, separated by :
:0 command name
:n n-th word, 0-indexed, of the command (= n-th argument, 1-indexed)
:x-y range of words from x to y (0-indexed, -y is synonymous with 0-y)
:^ 1st word, 0-indexed (= first argument)
:$ last word (= last argument)
:* all words but the zeroth (synonymous with 1-$)
:n* n-th (0-indexed) to last words (synonymous with n-$) (= n-th to last argument)
Shortcuts:
!* !:*
!$ !:$
!^ !:^
Modifiers:
Modifiers follow word designators, separated by :
:h head pathname (dirname)
:t tail pathname (basename)
:e suffix
:r remove suffix
:p print but not execute (TAB in mordern shell does this)
:q/:x quote substituted words to prevent further substitutions
:Q unquote words
:u uppercase all words
:l lowercase all words
:s/foo/bar/ replace foo with bar
:gs/foo/bar/ global replace foo with bar
!!:$:e suffix of the last argument of the last command
!!:$:h basepath of the last argument of the last command
ls /path/to/file/a.b.c
!$:h # /path/to/file
!$:t # a.b.c
!$:e # c
!$:r # /path/to/file/a.b
echo 1 2 3 4 5 6 7 8 9 10
!:q #'echo' '1' '2' '3' '4' '5' '6' '7' '8' '9' '10'
!:2-5 # 2 3 4 5
!:* # 1 2 3 4 5 6 7 8 9 10
!:1-3:s/1/foo/:s/2/bar/:s/3/baz/:q # 'foo' 'bar' 'baz'