6

I have my bash environment in vi mode (set -o vi). So I can type <ESC>/ followed by a word, followed by enter, and bash searches for the word in the history. Since / is also vi's method to search for regular expressions, I was under the expression that bash will search for regular expressions as well.

Unfortunately, when I type <ESC>/foo.*bar in bash, it does not find any line in the history that matches the regular expression foo.*bar.

Am I overlooking something or is it just not possible to search the history for regular expressions?

7
  • This question may be better suited for the Vi and Vim Stack Exchange Site.
    – Paradox
    Jun 29, 2016 at 19:01
  • 3
    @Paradox, but it is not really a vi question, is it? Jun 29, 2016 at 19:02
  • 3
    I don't have any more supporting evidence, but this page mentions that "the Readline library does not have a full set of vi editing functions, it does contain enough to allow simple editing of the line"
    – Jeff Schaller
    Jun 29, 2016 at 19:16
  • 1
    I usually search it by piping history command's output through grep to get a number for the historic command I was looking for. But that wouldn't answer the question
    – infixed
    Jun 29, 2016 at 20:46
  • 2
    This is not a vi question; this is a bash question. It’s possible that the users of Vi and Vim Stack Exchange will be able to answer it easily, but it is more on-topic here. Since the OP posted it here, it should stay here. If it doesn’t have a satisfactory answer after about 48 hours, then maybe we should consider migrating it. Jun 30, 2016 at 6:00

1 Answer 1

9

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).

3
  • 1
    I filed a bug report for this, fwiw: lists.gnu.org/archive/html/bug-readline/2016-08/msg00005.html So.. maybe some year soon (:
    – jwd
    Apr 26, 2018 at 17:00
  • I just stumbled upon my own question... and it is working in bash 5.0.16 (and probably in earlier versions, too) Mar 27, 2020 at 19:57
  • @jwd Thanks to your bug report and all the great work of the Bash maintainer and developers, this feature has been implemented for more than a year. :) Mar 28, 2020 at 0:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .