如何在 bash 中仅重复命令的一部分?

tel*_*tto 23 linux command-line bash

我想知道是否可以只重复命令的一部分。也就是说,如果我这样做ls /path/to/somewhere -a,我只想删除ls-a

我知道,如果我!!这样做,它会重复前一个命令(将最后一个命令附加到您在它之前编写的任何命令),并且如果我这样做,它!$会包含字符串的最后一部分,但我想知道是否可以重新- 仅使用前一个命令的例如中间部分。

ste*_*eve 27

当然可以,使用!^

例如

$ ls /path/to/somewhere -a
ls: cannot access '/path/to/somewhere': No such file or directory
$ echo !^
echo /path/to/somewhere
/path/to/somewhere
$
Run Code Online (Sandbox Code Playgroud)

或者(导致额外的击键)您可以使用!:1.

$ ls /path/to/somewhere -a
ls: cannot access '/path/to/somewhere': No such file or directory
$ echo !:1
echo /path/to/somewhere
/path/to/somewhere
$
Run Code Online (Sandbox Code Playgroud)

这在手册页事件指示符字指示符部分中有完整记录。bash


bis*_*hop 17

扩展@steve的答案来满足您的一般要求:

我想知道是否可以仅重用上一个命令的中间部分。

您可以使用多个单词范围来重新排列先前的命令:

  • !:x,要恢复第 x单词,第一个单词是第 0
  • !:x-y,恢复第 x第 y单词,包括在内

例如:

$ ls /foo /bar -a /baz >/dev/null 2>&1
$ echo !:1-2 !:4
echo /foo /bar /baz
/foo /bar /baz
Run Code Online (Sandbox Code Playgroud)

请注意,重定向运算符算作单个单词,因此:

$ ls /foo >/dev/null 2>&1
$ echo !:3 !:2
echo /dev/null >
bash: syntax error near unexpected token `newline'
Run Code Online (Sandbox Code Playgroud)

按索引进行的单词选择可以进一步扩展以适用于除最新命令之外的命令:

  • !-n,选择第n最近的命令
  • !string,选择最近的命令开头string

因此,结合这些你可以得到:

$ cat /foo -vet >/dev/null 2>&1
$ ls /bar -a >/dev/null 2>&1
$ cp !cat:1 !ls:1-2 >/dev/null 2>&1
cp /foo /bar -a
Run Code Online (Sandbox Code Playgroud)

我倾向于将命令历史记录视为一个数组——命令行,单词列——这使得这种导航变得自然。

需要注意的是:通过缝合旧命令的一部分来创建新命令可能会导致命令产生不可逆转的效果。我建议放置:p一个参数来显示构建的命令,而不是调用它。

例如:rm !ls:1-4:prm在插入最近命令的第 1到第 4参数后,这将打印最终命令ls


200*_*ess 5

Bash 有一个yank-last-arg用于处理命令历史记录的命令:

yank-last-arg(M-. 或 M-_)

将最后一个参数插入到上一个命令中(上一个历史记录条目的最后一个单词)。对于数字参数,其行为与 完全相同yank-nth-arg。连续调用将yank-last-arg在历史列表中向后移动,依次插入每行的最后一个单词(或第一次调用的参数指定的单词)。提供给这些连续调用的任何数字参数都决定了历史记录的移动方向。否定参数会切换历史的方向(向后或向前)。历史扩展工具用于提取最后一个参数,就像!$已指定历史扩展一样。

使用默认的按键绑定,您可以通过按 来激活它Meta.1 将最近命令的最后一个单词复制到光标所在的位置。

要复制第n单词而不是最后一个单词,请按Metan,然后按Meta.

我发现这比历史扩展更容易使用并且更不容易出错,因为它是交互式工作的。


另一种交互式调整先前命令的方法是使用该edit-and-execute-command功能:

编辑并执行命令 (Cx Ce)

在当前命令行上调用编辑器,并将结果作为 shell 命令执行。Bash 尝试按顺序调用$VISUAL$EDITOR、 和作为编辑器。emacs

使用向上/向下箭头键调用该命令,然后按CtrlX,CtrlE$EDITOR. 然后,您可以根据自己的喜好编辑命令,然后当您保存并退出编辑器时,它将执行。


1根据您的键盘布局,Meta可能意味着按住某个Alt键、按住某个Option键或按下并释放该Esc键。这.是句号或句号字符,以防您在此处阅读有困难。

  • 如果你的终端不糟糕,bash 行编辑与大多数编辑器一样好,除非行变得非常长。所以只需向上箭头、ctr-左箭头(向后的单词,尽管它停在 / 以及空格上)、ctrl-u(杀死行首)。或者按 ctrl-a(行首)、meta-d(删除字)两次,ls 和 -a 各一次。但是,是的,“meta-.”是迄今为止交互式使用的最佳答案;我一直使用它来执行诸如“mkdir foo”/“cd foo”之类的东西。我很惊讶其他人在此之前发布了不同的答案,其语法不容易记住,但在运行之前你看不到它是否有效。 (2认同)
  • 请注意,这仅适用于“emacs”模式。对于“vi”模式,请参阅https://superuser.com/questions/18498/last-parameter-of-last-command-in-bash-in-vi-mode (2认同)