# Bash history substitutions
# Quick Reference
# Interaction with the history
# List all previous commands history # Clear the history, useful if you entered a password by accident history -c
# Event designators
# Expands to line n of bash history !n # Expands to last command !! # Expands to last command starting with "text" !text # Expands to last command containing "text" !?text # Expands to command n lines ago !-n # Expands to last command with first occurrence of "foo" replaced by "bar" ^foo^bar^ # Expands to the current command !#
# Word designators
These are separated by
: from the event designator they refer to. The colon can be omitted if the word designator doesn't start with a number:
!^ is the same as
# Expands to the first argument of the most recent command !^ # Expands to the last argument of the most recent command (short for !!:$) !$ # Expands to the third argument of the most recent command !:3 # Expands to arguments x through y (inclusive) of the last command # x and y can be numbers or the anchor characters ^ $ !:x-y # Expands to all words of the last command except the 0th # Equivalent to :^-$ !*
These modify the preceding event or word designator.
# Replacement in the expansion using sed syntax # Allows flags before the s and alternate separators :s/foo/bar/ #substitutes bar for first occurrence of foo :gs|foo|bar| #substitutes bar for all foo # Remove leading path from last argument ("tail") :t # Remove trailing path from last argument ("head") :h # Remove file extension from last argument :r
If the Bash variable
HISTCONTROL contains either
ignoreboth (or, alternatively,
HISTIGNORE contains the pattern
[ ]*), you can prevent your commands from being stored in Bash history by prepending them with a space:
# This command won't be saved in the history foo # This command will be saved bar
# Repeat previous command with sudo
$ apt-get install r-base E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root? $ sudo !! sudo apt-get install r-base [sudo] password for <user>:
# Search in the command history by pattern
Press controlr and type a pattern.
For example, if you recently executed
man 5 crontab, you can find it quickly by starting to type "crontab". The prompt will change like this:
(reverse-i-search)`cr': man 5 crontab
The ``cr'` there is the string I typed so far. This is an incremental search, so as you continue typing, the search result gets updated to match the most recent command that contained the pattern.
Press the left or right arrow keys to edit the matched command before running it, or the enter key to run the command.
By default the search finds the most recently executed command matching the pattern. To go further back in the history press controlr again. You may press it repeatedly until you find the desired command.
# Switch to newly created directory with !#:N
$ mkdir backup_download_directory && cd !#:1 mkdir backup_download_directory && cd backup_download_directory
This will substitute the Nth argument of the current command. In the example
!#:1 is replaced with the first argument, i.e. backup_download_directory.
# Using !$
You can use the
!$ to reduce repetition when using the command line:
$ echo ping ping $ echo !$ ping
You can also build upon the repetition
$ echo !$ pong ping pong $ echo !$, a great game pong, a great game
Notice that in the last example we did not get
ping pong, a great game because the last argument passed to the previous command was
pong, we can avoid issue like this by adding quotes. Continuing with the example, our last argument was
$ echo "it is !$ time" it is game time $ echo "hooray, !$!" hooray, it is game time!
# Repeat the previous command with a substitution
$ mplayer Lecture_video_part1.mkv $ ^1^2^ mplayer Lecture_video_part2.mkv
This command will replace
2 in the previously executed command. It will only replace the first occurrence of the string and is equivalent to
If you want to replace all occurrences, you have to use