The short answer is that you can not use regular expressions to search the shell history. According to POSIX (the standard for Unix-like operating systems), you should be able to search using regular shell pattern matching (as used for filename globbing and with case
statements). This feature is referred to as non-incremental search but it currently does not seem to be correctly implemented in Bash.
POSIX specification
The POSIX specification for shell Command Line Editing (vi-mode) states that these search patterns should use regular shell pattern matching. While the ^
meta-character is used to match the start of a line, they are not regular expressions.
/pattern<newline>
Move backwards through the command history, searching for the specified
pattern, beginning with the previous command line. Patterns use the pattern
matching notation described in Pattern Matching
Notation
, except that the '^' character shall have special meaning when it appears
as the first character of pattern. In this case, the '^' is discarded and
the characters after the '^' shall be matched only at the beginning of a
line. Commands in the command history shall be treated as strings, not as
filenames.
Documented Bash implementation
Bash uses the GNU Readline library to provide its interactive line-editing and history searching capabilities. The official documentation for the Readline library focuses more on Emacs mode, but a short section in its manual, Readline vi Mode states that
While the Readline library does not have a full set of vi editing functions,
it does contain enough to allow simple editing of the line.
The Readline vi mode behaves as specified in the POSIX standard.
Actual Bash implementation
After a number of experiments on two different systems, I found that the non-incremental searching in Bash/Readline does not work as described in its official documentation. I found that the *
was treated as a literal asterisk rather than a pattern that matches multiple characters. Likewise, the ?
and [
are also treated as literal characters.
For comparison, I tried using Vi-mode in tcsh
and verified that it correctly implements history searching as specified in the POSIX standard.
I then downloaded and searched through the code for the Readline library and found its history searching functions use a simple substring search and don’t use any search pattern meta-characters – aside from the caret, ^
(see search.c from the git repository for the Readline library).
I presume the Bash/Readline developers have yet to implement this feature. I couldn’t find a bug-list but the CHANGES
files shows that they’ve been regularly fixing issues relating to Vi-mode.
Update: This feature was implemented in Readline 8.0 (released with Bash 5.0 in January 2019). As documented in its CHANGES:
New Features in Readline
a. Non-incremental vi-mode search (N
, n
) can search for a shell pattern, as Posix specifies (uses fnmatch(3)
if available).
history
command's output throughgrep
to get a number for the historic command I was looking for. But that wouldn't answer the question