AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 523543
Accepted
guettli
guettli
Asked: 2019-06-08 05:39:54 +0800 CST2019-06-08 05:39:54 +0800 CST 2019-06-08 05:39:54 +0800 CST

在 bash 中替代 Ctrl-R 反向搜索

  • 772

我很高兴并且非常喜欢 bash shell 的Ctrl向后R搜索功能。我的一些同事不喜欢它,因为它有时会令人困惑。我理解他们。如果您输入了错误的字符,则历史中的当前位置是过去的某个位置,您将找不到最近的匹配项。

在 shell 历史中向后搜索是否有更用户友好的替代方法?

我想坚持使用 bash。建议替代外壳不是这个问题的答案。

这里解释了“丢失位置”的问题:Reset bash history search position。这些解决方案有效。这是正确的。但是根据我的观点,那里的解决方案并不容易且用户友好。这些解决方案并不简单直接。这些都是过去的解决方案。在过去,人类需要学习计算机想要输入的方式。但是今天,这些工具应该以一种对用户来说很容易的方式接受输入。

也许有人知道像 PyCharm 这样的 jetbrains IDE。如果您搜索“foobar”,您甚至会得到包含“foo_bar”的行。太好了,这就是 unix :-)

bash command-history
  • 5 5 个回答
  • 5616 Views

5 个回答

  • Voted
  1. Best Answer
    Tim Friske
    2019-06-08T11:39:04+08:002019-06-08T11:39:04+08:00

    我正在使用模糊查找程序FZF。我编写了自己的键绑定和 shell 脚本,以利用FZF作为我选择的工具来反向搜索交互式Bash shell 的历史。随意从我的Config GitHub 存储库中复制和粘贴代码。

    ~/.bashrc 配置文件

    # Test if fuzzy finder program _Fzf_ is installed.
    #
    if type -p fzf &> /dev/null; then
    
      # Test if _Fzf_ specific _Readline_ file is readable.
      #
      if [[ -f ~/.inputrc.fzf && -r ~/.inputrc.fzf ]]; then
    
        # Make _Fzf_ available through _Readline_ key bindings.
        #
        bind -f ~/.inputrc.fzf
      fi
    fi
    

    ~/.inputrc.fzf 配置文件##

    $if mode=vi
    
      # Key bindings for _Vi_ _Insert_ mode
      # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      set keymap vi-insert
    
      "\C-x\C-a": vi-movement-mode
      "\C-x\C-e": shell-expand-line
      "\C-x\C-r": redraw-current-line
      "\C-x^": history-expand-line
      "\C-r": "\C-x\C-addi$(HISTTIMEFORMAT= history | fzf-history)\C-x\C-e\C-x\C-r\C-x^\C-x\C-a$a"
    
      # Key bindings for _Vi_ _Command_ mode
      # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      set keymap vi-command
    
      "\C-r": "i\C-r"
      "\ec": "i\ec"
    
    $endif
    

    fzf-history 可执行 Bash 脚本

    #!/usr/bin/env bash
    #
    # Retrieve command from history with fuzzy finder
    # ===============================================
    # Tim Friske <[email protected]>
    #
    # See also:
    #   * man:bash[1]
    #   * man:fzf[1]
    #   * man:cat[1]
    
    shopt -os nounset pipefail errexit errtrace
    shopt -s extglob globstar
    
    function print_help {
      1>&2 cat \
    <<'HELP'
    usage:
      HISTTIMEFORMAT= history | fzf-history
    HELP
    }
    
    function fzf_history {
      if [[ -t 0 ]]; then
        print_help
        exit
      fi
    
      local fzf_options=()
      fzf_options+=(${FZF_DEFAULT_OPTS:-})
      fzf_options+=('--tac' '-n2..,..' '--tiebreak=index')
      fzf_options+=(${FZF_HISTORY_FZF_OPTS:-})
      fzf_options+=('--print0')
    
      local cmd='' cmds=()
      while read -r -d '' cmd; do
        cmds+=("${cmd/#+([[:digit:]])+([[:space:]])/}")
      done < <(fzf "${fzf_options[@]}")
      if [[ "${#cmds[*]}" -gt 0 ]]; then
        (IFS=';'; printf '%s\n' "${cmds[*]}")
      fi
    }
    
    fzf_history "$@"
    

    key-bindings.bash 源 Bash 脚本

    取自FZF 的 Bash 键绑定文件并稍作改编,这里是用于 Bash 历史反向搜索的 Emacs 模式兼容键绑定Ctrl-R(未经测试):

    if [[ ! -o vi ]]; then
      # Required to refresh the prompt after fzf
      bind '"\er": redraw-current-line'
      bind '"\e^": history-expand-line'
    
      # CTRL-R - Paste the selected command from history into the command line
      bind '"\C-r": " \C-e\C-u\C-y\ey\C-u$(HISTTIMEFORMAT= history | fzf-history)\e\C-e\er\e^"'
    fi
    
    • 4
  2. ctrl-alt-delor
    2019-06-08T07:15:45+08:002019-06-08T07:15:45+08:00
    • 向上箭头:仅适用于最近的东西。
    • grep blablabla ~/.bash_history:您必须设置 bash 以在每个命令后将历史记录保存到文件中。

    从我的~/.bashrc你可能想了解命令的作用和调整。

    # don't put duplicate lines in the history. See bash(1) for more options
    HISTCONTROL=ignorespace:ignoredups:erasedups
    HISTFILESIZE=99999
    HISTSIZE=99999
    export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
    # append to the history file, don't overwrite it
    shopt -s histappend
    #history
    shopt -s cmdhist
    shopt -s histreedit
    shopt -s histverify
    shopt -s lithist
    
    • 2
  3. pizdelect
    2019-06-08T14:57:05+08:002019-06-08T14:57:05+08:00

    对于它的价值,如果您禁用 tty 的停止/启动功能(您可能不会使用那么多),您可以通过按 Control-S 来更改搜索方向。

    % stty stop undef
    
    % true str1
    % true str2
    % true str3
    % true str4
    Control-R => (reverse-i-search)`str': true str4
    Control-R => (reverse-i-search)`str': true str3
    Control-S => (i-search)`str': true str3
    Control-S => (i-search)`str': true str4
    

    至于那些不是“用户友好”或不直观的键绑定,它们是 emacs 键绑定。emacs并不适合所有人,这并不奇怪(尽管我知道秘书和其他不那么自命不凡的人能够立即掌握它们并且没有大惊小怪)。这更像是一种文化。

    • 1
  4. Timmmm
    2021-12-08T03:00:12+08:002021-12-08T03:00:12+08:00

    McFly是另一种选择。它非常易于安装 - 您可以通过brew或下载最新的二进制文件来完成。它是用 Rust 编写的,所以它们是静态链接的。没有依赖废话。

    然后只需将其添加到您的.bashrc/ .zshrc:

    eval "$(mcfly init bash)" # or zsh
    

    它为您提供以某种智能方式排序的全屏 UI。

    在此处输入图像描述

    • 0
  5. sm7
    2021-05-26T01:38:19+08:002021-05-26T01:38:19+08:00

    FZF支持 bash(还有 zsh 和 fish)。

    @Tim Freske 的回答描述了他们对 vi 样式键绑定的修改。

    默认键绑定是 emacs 样式。这甚至会覆盖Ctrl-r行为以模糊查找而不会丢失位置。默认情况下它们可能未启用。要启用它们,请将其添加到.bashrc:

    source /usr/share/doc/fzf/examples/key-bindings.bash
    

    (如果这不起作用,执行apt-cache show fzf并查找...fzf/README...文件,它会列出 bash、zsh、fish 和 vim 的命令)

    • -1

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve