4 ms·
The things he calls "bang commands" are actually "event designators" (!!, !blah), "word designators" ($) and "word modifiers" (:p). There are links to docs for
by unfletch 15y ago
The things he calls "bang commands" are actually "event designators" (!!, !blah), "word designators" ($) and "word modifiers" (:p). There are links to docs for each at the bottom of this page: http://www.gnu.org/s/bash/manual/html_node/History-Interaction.html#History-Interaction http://www.gnu.org/s/bash/manual/html_node/History-Interacti...
I use them all the time, and anyone watching over my shoulder always asks what that was. Learn !!, !$, and a few modifiers. You'll be glad you did. Personally, I use !$ constantly (and variations like !-2$, which gets you the last arg from 2 commands ago). The "h" modifier is handy, too. It's like dirname for the word. Consider this example, where you copy a file to some deep path, and then cd to that dir to continue working with the copy:
$ cp foo.txt /some/really/long/destination/bar.txt
$ cd !$:h
$ # (do more with ./bar.txt)
The substitution (:s) and global substitution (:gs) modifiers are also useful:
$ echo some args
some args
$ !!:s/some/more
more args
(Also, note that his explanation of !* is actually incorrect. He says it leaves off the last arg, but actually leaves out $0 (the command name). !* is all of the previous command's arguments.)
Finally, one really useful thing he doesn't mention at all is brace expansion. For example, these are equivalent:
$ cp foo.conf foo.conf.bak
$ cp foo.conf{,.bak}
http://www.gnu.org/s/bash/manual/html_node/Brace-Expansion.html http://www.gnu.org/s/bash/manual/html_node/Brace-Expansion.h...
- drothlis 15y agoI used to use !$ all the time, but these days I tend to go for M-. which inserts the last argument interactively, and cycles through the last argument of all previous commands (but you don't get modifiers like !$:h). http://www.gnu.org/s/bash/manual/html_node/Commands-For-History.html#Commands-For-History http://www.gnu.org/s/bash/manual/html_node/Commands-For-Hist... M-C-y (yank-nth-arg) works similarly for the first argument of the previous command, but without cycling through all previous commands. After the more complex modifiers like !$:p, :e, :s/old/new/, etc, before hitting Return I often use M-C-e (shell-expand-line) just to check I got it right. http://www.gnu.org/s/bash/manual/html_node/Miscellaneous-Commands.html#Miscellaneous-Commands http://www.gnu.org/s/bash/manual/html_node/Miscellaneous-Com...
- pyre 15y agoA neat thing about csh/tcsh is that you can use history expansion with aliases. There are some legacy aliases at work that allow SQL queries from the command line using this: $ alias select='sqlcommand -s "select !*"' would translate: $ select * from tablename to: $ sqlcommand -s "select * from tablename" (Note: I may be getting the specifics messed up as it's been a couple of years since I looked at the implementation, but the general idea is there.)
- pooriaazimi 15y agoThank you! The backup tip was great. I never thought of using expansion like that... You post inspired me to quickly create two (hopefully) handy bash functions: # Create a backup of the given file(s) # USAGE: bk file1 file2 file3 # -> result: file1.bak file2.bak file3.bak bk() { for file in "$@" do cp $file{,.bak} done } # Restores the file from backup # USAGE: rbk file.bak OR rbk file # -> result: replaces file with file.bak rbk() { if [[ $1 == *.bak ]] then backup_file=$1 old_file=${backup_file:0:$((${#backup_file}-4))} else old_file=$1 backup_file=${old_file}".bak" fi read -p "Replace the old backup? (y/N) " -n 2 echo if [[ $REPLY =~ ^[Yy]$ ]]; then `cp $backup_file $old_file` fi } I've put them in my newly created .functions file (https://github.com/pooriaazimi/dotfiles/blob/master/.functions https://github.com/pooriaazimi/dotfiles/blob/master/.functio...).
- gbog 15y ago!! and !$ are alright, but I really dislike !blah, which is blindly executing the latest command starting with blah, whatever it is. The author of the article should remove this "tip", it is bad advice, or at least make a note that the !blah:p is highly preferable.
- spiffytech 15y agoI prefer using Ctrl-r <blah>, which searches your history for 'blah' and puts it on the command line. The preferable part is that you can keep hitting Ctrl-r to see previous matches, which is often helpful since you don't want the last match, but the second or third match.
- apu 15y agoA small change that made it much easier for me to use ! commands was enabling magic space, which expands the ! macros out when you press space. This made an enormous difference to me, since I could now be sure I wasn't accidentally completing the wrong command or arguments. To enable it, edit your .inputrc (this is part of readline) and add this: $if Bash Space: magic-space $endif
- mrud 15y agoI am using follow function for cd which does basically the same though i can iterate through the last arguments with alt+. cd () { if [[ -f $1 ]] then builtin cd $1:h else builtin cd "$@" fi }