bash 中 Ctrl-R 反向搜尋的替代方案

bash 中 Ctrl-R 反向搜尋的替代方案

我很高興並且非常喜歡bash shell 的向後搜尋功能CtrlR我的一些同事不喜歡它,因為它有時會令人困惑。我理解他們。如果您輸入錯誤的字符,則歷史記錄中的當前位置是過去的某個位置,並且您將找不到最近的匹配項。

是否有更用戶友好的替代方案可以在 shell 歷史記錄中向後搜尋?

我想堅持使用 bash。建議使用替代 shell 並不能解決這個問題。

「丟失位置」的問題解釋如下:重置 bash 歷史搜尋位置。這些解決方案有效。這是正確的。但根據我的觀點,那裡的解決方案並不簡單且用戶友好。這些解決方案並不簡單直接。這些都是過去的解決方案。過去,人類需要按照電腦想要的輸入方式來學習。但今天的工具應該以一種對使用者來說容易的方式接受輸入。

也許有人知道像 PyCharm 這樣的 jetbrains IDE。如果您搜尋“foobar”,您甚至會得到包含“foo_bar”的行。太棒了,那是 unix :-)

答案1

我正在使用模糊查找程序弗茲弗。我已經編寫了自己的鍵綁定和 shell 腳本來使用弗茲弗作為我選擇的反向搜尋互動式工具重擊殼牌的歷史。請隨意複製並貼上我的程式碼配置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 歷史反向搜尋的 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

答案2

  • 向上箭頭:僅適用於最近的東西。
  • 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

答案3

麥克弗萊是另一種選擇。安裝非常簡單 - 您可以透過安裝brew或直接下載最新的二進位文件。它是用 Rust 編寫的,因此它們是靜態連結的。沒有依賴廢話。

然後只需將其添加到您的.bashrc/ .zshrc

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

它為您提供了以某種智慧方式排序的全螢幕使用者介面。

在此輸入影像描述

答案4

弗茲弗支援 bash(還有 zsh 和 Fish)。

@蒂姆·弗雷斯克的回答描述了他們對 vi 風格鍵綁定的修改。

預設鍵綁定是emacs風格。這甚至會覆蓋Ctrl-r行為以模糊查找而不丟失位置。預設情況下它們可能未啟用。要啟用它們,請將其添加到.bashrc

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

(如果這不起作用,請執行apt-cache show fzf並查找...fzf/README...文件,它列出了 bash、zsh、fish 和 vim 的命令)

相關內容