![bash 中 Ctrl-R 反向搜索的替代方案](https://linux22.com/image/155042/bash%20%E4%B8%AD%20Ctrl-R%20%E5%8F%8D%E5%90%91%E6%90%9C%E7%B4%A2%E7%9A%84%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88.png)
我很高兴并且非常喜欢bash shell 的向后搜索功能Ctrl。R我的一些同事不喜欢它,因为它有时会令人困惑。我理解他们。如果您输入错误的字符,则历史记录中的当前位置是过去的某个位置,并且您将找不到最近的匹配项。
是否有更用户友好的替代方案可以在 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
答案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 的命令)