如何快速更改 Bash 命令中的第一个单词?

now*_*wox 45 linux bash shell command-line

我想用 Bash 稍微改进我的工作流程,我意识到我经常想对不同的可执行文件执行相同的命令。

一些例子:

Git(我想快速更改第二个词):

git diff     foo/bar.c
git checkout foo/bar.c
Run Code Online (Sandbox Code Playgroud)

Cat/rm(只需更改第一个单词):

cat foo/is/a/very/long/path/to/bar.c
rm  foo/is/a/very/long/path/to/bar.c
Run Code Online (Sandbox Code Playgroud)

我知道我可以点击Ctrl+ athenDel删除第一个单词,但我想知道是否有更快的方法来做到这一点。

Spi*_*iff 57

!$ 扩展到上一个命令的最后一个单词。

所以你可以这样做:

cat foo/is/a/very/long/path/to/bar.c

rm !$
Run Code Online (Sandbox Code Playgroud)

或者:

git diff foo/bar.c

git checkout !$
Run Code Online (Sandbox Code Playgroud)

你的例子碰巧只重复了最后一个词,所以!$效果很好。如果您实际上有很多要重复的参数,而您只想更改第一个单词,则可以使用!*,它将扩展为除第零个之外的前一个命令的所有单词。

请参阅bash手册页的“历史扩展”部分。那里有很大的灵活性。

  • 正确和适当。我只想放一个**警告**:使用`!$` 你**没有对正在运行的行进行完全可视化控制**。这有时会导致有害。特别是如果您遇到印刷错误。它需要从“历史”中扩展什么。所以如果你写的最后一条命令在开头有一个空格,那么这个命令可能不会在历史记录中完成。当你用 `!$` 执行你的新命令时,shell 不会从最后一个输入的命令行中获取参数,而只会从最后一个历史记录中获取参数。**[此处](http://superuser.com/a/776767/257269)** 相同的词。 (16认同)
  • @Hastur 这就是为什么你需要在 zsh 中按两次介绍(无耻的促销) (2认同)

jjl*_*lin 28

Ctrl+a转到行首,然后Alt+d删除第一个单词。

  • 删除词的快捷方式其实就是Meta+d,在Linux机器上Meta通常映射到Alt。在不是这种情况的平台上,获得 Meta 修饰符的另一种方法是使用 Escape 作为前缀。见 http://en.wikipedia.org/wiki/Meta_key (9认同)
  • @GustavoGiráldez 如果您想深入了解,那么只有在启用了 emacs(通过 set -o emacs 或默认情况下)时,Meta+D 才有效。它不会在 * 低级编辑器 * 模式下工作,或者如果 `emacs` 被禁用。 (2认同)

小智 17

我不确定它是否真的会更快,但请参阅这篇文章,特别是第 #.3 点:

  1. 使用 ^str1^str2^ 替换上一个命令中的字符串

在以下示例中,我们首先执行 ls 命令来验证文件。后来我们意识到我们要查看文件的内容。无需再次输入整个文件名,我们只需将上一个命令中的“ls”替换为“cat”,如下所示。

$ ls /etc/cron.daily/logrotate

$ ^ls^cat^
cat /etc/cron.daily/logrotate
Run Code Online (Sandbox Code Playgroud)


Has*_*tur 16

Alt+.

如果您只需要重复前一个命令的最后一部分,您可以使用Alt+.粘贴从历史记录最后一行获取的最后一个参数。

如果按下多次,将用之前该行的最后一个参数替换刚刚粘贴的内容...

例如,如果最后 2 个命令是:

cat foo/is/a/very/long/path/to/bar.c
pico foo/is/a/very/long/path/to/SomeWhereElse.c
Run Code Online (Sandbox Code Playgroud)

在我写的 shell 中rm,我按下Alt+.它会出现:

rm foo/is/a/very/long/path/to/SomeWhereElse.c
Run Code Online (Sandbox Code Playgroud)

如果我再次按下Alt+.它会出现

rm foo/is/a/very/long/path/to/bar.c
Run Code Online (Sandbox Code Playgroud)

等等...


mai*_*iki 12

除了@jjlin 的回答,您可能会对以下提示感兴趣:

  • Ctrl+w删除你左边的单词
  • Ctrl+k从光标处删除到命令行末尾
  • Ctrl+u从光标处删除到命令行的开头
  • Alt+b光标向后移动一个字
  • Alt+f将光标向前移动一个字
  • $_ 包含上一个命令行的最后一个参数

有关这些的更多信息,请查找bash联机帮助页的“Readline 命令名称”部分。

例如:

cat foo/is/a/very/long/path/to/bar.c
rm $_
Run Code Online (Sandbox Code Playgroud)


Cha*_*ed0 8

如果您精通 vi,则可以使用命令在 bash(大多数 shell?)中激活 vi 绑定set -o vi。然后,您可以使用普通的 vi 键来编辑您的命令。在您的第一个示例中,您可以^wcw删除“diff”,然后将其更改为结帐。

仅仅为了编辑命令行而学习 vi 键绑定可能不值得,但如果您已经了解它们,它会大大提高生产力。


Dan*_*ner 6

有很多方法可以给这只猫剥皮!

要替换特定字符串,^old^new^extra将采用您之前的命令,替换oldnew,然后追加extra。您可以随时停止;eg^old将替换old为空字符串并附加空字符串(本质上是删除old并且什么也不做)。

1. ^diff^checkout
2. ^cat^rm
Run Code Online (Sandbox Code Playgroud)

特别有用的变体:

for i in `seq 1 10`; do echo something complicated; done
# inspect the output to see if it looks right
^echo
Run Code Online (Sandbox Code Playgroud)

要替换特定的单词,您可以使用通过命令!m:n-p来引用单词(使用负数从当前命令开始倒数)。您可以省略部分以引用单个单词,也可以省略部分以引用整个命令。特殊形式为,为前一个命令的最后一个字,并为参数(所有,但字上一个命令的)都非常方便。npm-p:m-p!!!-1!$!*0

1. !!:0 checkout !!:2-
2. rm !*
Run Code Online (Sandbox Code Playgroud)

我经常使用这两种方法;zsh 在这里特别好,因为点击选项卡将扩展神秘的东西以确保你做对了。

通过行编辑也有很多方法可以做到这一点。阅读您的 shell 的键绑定。