Bash history expansion
Apparently, histexpand (set -o histexpand
) must be in effect for history expansion to work.
Using !
The exclamation mark can be used to refer to portions of one of the last commands executed.
!!
is expanded to the last command. So
$ !!
repeats the last command.
A useful application for this construct is if
sudo was forgotten:
$ pacman -Syu
error: you cannot perform this operation unless you are root.
$ sudo !!
Repeat the most recent command that
starts with ls:
$ !ls
Repeat the most recent command that contains foo:
$ !?foo
:p
does not execute the command but rather prints it:
$ !ls:p
!^ and !$
!^
is replaced with the first argument:
$ echo foo bar baz
foo bar baz
$ echo abc !^ def
abc foo def
Similarly, !$
is replaced with the last argument.
nth argument
Similar to !^
and !$
, the nth argument can be referred to with !!:n
:
$ echo one two three
one two three
$ echo !:3 !:2 !:1
three two one
!^
and !!:^
seem to be equivalent, as well as also !$
and !!:$
.
All arguments are referred to with !!:*
Arguments n through m are referred to with !!:n-m
Arguments n and following are referred to with !!:n*
Searching for commands
!?text?
searches for the last command that contained text
and executes it.
Substituting elements in previous commands
!!s/text/replacement/
substitutes the first occurence of word:
$ !!:s/foo/bar/
gs/text/replacement/
substitutes every occurence of word (g
=global).
:&
reuses the last substitution:
!ls:&
^text^replacement^
^text^replacement^
replaces text
in the last command with replacement
.
$ ls -l tmp
$ ^-l^-la^
!n and !-n
As !!
refers to the last command, !-n
refers to the n-th last command and !n
to command with number n
(as printed with the history
command).
As a convenience,
$PS1
can be set to something like
export PS1="\!$ "
to always print the current history number which can be used in
!n
.
Modifiers
The modifiers :h
, :t
, :r
and :e
can be used to select parts of a directory and/or file path:
#!/bin/sh
echo "PS1=
echo /path/to/a/file.extension
echo !-1:$:h # head, expands to /path/to/a
echo !-2:$:t # tail, expands to file.extension
echo !-3:$:r # remove extension, expands to /path/to/a/file
echo !-4:$:e # extension only, expands to .extension
echo !-5:$:t:r # Remove extension from tail, expands to file
" | bash -i # Use -i to start interactive shell
histappend
By default, bash overwrites the history when the session ends. With setting histappend (shopt -s histappend
), bash appends the commands executed during a session when it ends.