【问题标题】:Get output from fzf in the terminal without executing it从终端中的 fzf 获取输出而不执行它
【发布时间】:2017-12-10 00:24:36
【问题描述】:

fzf 摇滚!我想用它来搜索 bash 历史记录。找到匹配项后,我希望将其放在命令行上,但 not 已执行,因此我可以进一步编辑它。 (所有这些都在一个有源的 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 就可以了,但它不起作用。

【问题讨论】:

  • 有什么理由不使用反向搜索(Ctrl 和 r)?
  • 我从来不习惯使用它。我刚试过。 fzf 好很多。它让我可以一次看到许多替代方案,并提供更多搜索选项,而不仅仅是一次。而且,我没有看到编辑我发现的内容的方法。当我按 Enter 时,它只是运行未修改的命令。此外,如果我能弄清楚这一点,它可能会为自动获取命令行上的内容以供我使用提供其他可能性。
  • 您可以多次按 Ctrl-r 来浏览与输入文本相关的不同选项。然后您可以按 Escape 以获取命令行上的命令进行编辑。我建议在花时间尝试设计自己的选项之前花时间研究已经可用的选项
  • 另外,如果您想在屏幕上显示与搜索相关的所有不同选项,您可以简单地使用历史记录并通过 grep 管道进行搜索。然后您可以使用 ! 来执行命令
  • @RamanSailopal 这些都是很好的建议。除了使用向上箭头返回之外,我没有对历史做太多事情。偶尔,我尝试一个!后面跟着一些字符,但这很危险,因为它会在您查看它是否选择您认为的内容之前运行它。尽管如此,fzf 似乎很受欢迎,所以我不是唯一一个从中发现价值的人。此外,这些工具需要几行代码才能实现。我不是在编写自己的文本编辑器或新版本的 mencoder。

标签: bash terminal fzf


【解决方案1】:

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

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

历史验证

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

最后,bash 的内置fc(通过help 了解更多信息,而不是man)除了支持history 内置功能之外,还支持“显示[ing] 或执行[ing] 历史列表中的命令”专注于“显示或操作历史列表”。


还要注意...

fzf's key-bind.bashsn-p:

  # 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,则用户有机会重新编辑失败的历史替换。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 您能否举例说明我们应该如何使用它?我像这样使用它alias scripts=ls ~/dotfiles/scripts | sed -e 's/\..*$//' | fzf-file-widget,但我收到一个错误"fzf-file-widget:zle:4: widgets can only be called when ZLE is active"
      【解决方案4】:

      我没有意识到这从未得到完全回答。我最终编写了一个位于 $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
      

      .bashrc,将函数绑定到Ctrl+f,方便使用和记忆。

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

      【讨论】:

        【解决方案5】:

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

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

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

        例如vim CTRL-T

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-11-10
          • 2020-01-22
          • 2013-01-25
          • 2020-09-07
          • 1970-01-01
          • 2013-09-06
          • 1970-01-01
          相关资源
          最近更新 更多