7

fzf 摇滚!我想用它来搜索 bash 历史记录。找到匹配项后,我希望将其放在命令行上,但执行,以便进一步编辑。(所有这些都在一个有源的 bash 函数或脚本中,因此它可以访问我的历史记录。)

我几乎可以正常工作,但不完全正常。

这会选择命令,但会立即运行它:

eval $(history | "$HOME/bin/fzf" +s | sed 's/ *[0-9]* *//')

这会将它放入我的剪贴板,但是当我粘贴它时,它仍然以空白和换行符结尾,因此它会立即执行。

history | "$HOME/bin/fzf" +s | sed 's/ *[0-9]* *//' | xclip -se c

我还尝试了几种变体,包括

history | "$HOME/bin/fzf" +s | sed -e 's/ *[0-9]* *//' -e 's/$//' | xclip -se c

结果相同。

这确实有效,但我仍然必须将其放入剪贴板,然后手动粘贴。

history | "$HOME/bin/fzf" +s | sed -re 's/ *[0-9]* *//' | awk '{printf "%s", $0}' | xclip -se c

如何一步完成 - 无需手动粘贴?

我以为只要不使用 xclip 就可以了,但它不起作用。

4

5 回答 5

2

fzf准备在@sudavid4 提到的fzf 的 key-bindings.bash中安装此功能。__fzf_history__函数使用 fzf 以交互方式搜索 bash 历史记录。

在默认历史处理中(尽管 fzf 的功能不需要),通过设置启用选择后编辑histverify。来自man bash

历史验证

如果设置,并且正在使用 readline,历史替换的结果不会立即传递给 shell 解析器。相反,结果行被加载到 readline 编辑缓冲区中,允许进一步修改。

最后,bash 的内置函数(通过, notfc了解更多信息)除了专注于“显示或操作历史列表”的内置函数外,还支持“从历史列表中显示 [ing] 或执行 [ing] 命令” 。helpmanhistory


还要注意...

fzf 的 key-bind.bash片段:

  # CTRL-R - Paste the selected command from history into the command line
  bind -m emacs-standard -x '"\C-r": __fzf_history__'
  bind -m vi-command -x '"\C-r": __fzf_history__'
  bind -m vi-insert -x '"\C-r": __fzf_history__'

具有相关但不同目的的相邻 bash shopt(shell 选项):

历史编辑

如果设置,并且正在使用 readline,则用户有机会重新编辑失败的历史替换。

于 2021-02-09T20:05:48.647 回答
1

在当前的 fzf 版本中,您可以使用ctrl-r从命令行执行此操作。从自述文件

CTRL-R- 将所选命令从历史记录粘贴到命令行

于 2020-03-24T13:23:41.193 回答
0

在我看来,junegunn 已经为您解决了这个问题。在此文件中,他将 bash ctrl-r 替换为您所追求的功能。fzf-file-widget由于行输出,我确实在采购这个文件时遇到了一个小问题sh: ``fzf-file-widget': not a valid identifier,但是在更改它之后fzf_file_widget它工作得很好。

于 2018-02-12T16:27:26.067 回答
0

我希望通过 fzf 打开文件(不是历史记录)的这种行为。

检查@mcint 共享的链接:fzf 的 key-bind.bash帮助我解决了我的用例:

CTRL-T:将选定的文件路径粘贴到命令行中。

例如 vim CTRL-T

通过使用这种方法,具有扩展文件名的命令会显示在 bash 历史记录中。

于 2021-12-16T12:26:07.097 回答
0

我没有意识到这从未得到完全回答。我最终编写了一个位于 $HOME/.bashrc 中的函数。

它仍然需要按粘贴 (Ctrl+Shift+v) 才能在命令行上获得结果。

# fh - repeat history
fh () 
{ 
    history | tac | "$HOME/bin/fzf" +s | sed -re 's/ *[0-9]* *//' | awk '{printf "%s", $0}' | xclip -se c
}

它将所选命令行留在剪贴板中,因此您可以将其粘贴到命令行中以进行进一步编辑和执行。

它通过管道将 CLI 历史记录tac颠倒过来,以便最近的命令首先显示(在最后)并将其发送到fzf. +s告诉fzf不要再次对输出进行排序。接下来,sed用于从结果中去除命令编号前缀。然后awk它会从命令中删除尾随的换行符,这样它就不会在粘贴后立即运行。最后,xclip用于将所选内容放入剪贴板。

最后,我添加

bind '"\C-F":" fh\n"'  # fzf history on ctrl+F

to.bashrc绑定函数,Ctrl+f使其易于使用和记忆。

我在绑定命令中添加了一个前导空格,fh以便在调用它时不会将其添加到命令历史记录中。

于 2020-04-14T19:03:52.983 回答