331

我知道Esc+.给了你最后一个命令的最后一个参数。

但我对最后一个命令的第一个参数感兴趣。是否有键绑定可以这样做?

在同一行中,是否有从最后一个命令获取第 n 个参数的通用方法?我知道在 bash 脚本中,您可以使用$0$1,但这些在命令行上不起作用。

此外,如何遍历先前命令的第 0 个参数,就像我们可以通过连续按Esc+来处理最后一个参数一样.

4

11 回答 11

372

!$获取前一个命令行参数的最后一个元素。

于 2013-01-06T16:12:06.050 回答
304

正如M-.(meta-dot or esc-dot or alt-dot) 是 readline 函数一样yank-last-argM-C-y(meta-control-y or esc-ctrl-y or ctrl-alt-y) 是 readline 函数yank-nth-arg。如果不指定n,它会拉出上一个命令的第一个参数。

要指定参数,请按 Escape 和数字或按住 Alt 并按数字。你可以这样做Alt--开始指定一个负数,然后释放 Alt 并按下数字(这将从参数列表的末尾开始计算。

例子:

输入以下命令

$ echo a b c d e f g
a b c d e f g

现在在下一个提示符下,输入echo(后面有空格),然后

Alt- Ctrl-y你现在会看到:

$ echo a

无需按下Enter,请执行以下操作

Alt- 3 Alt- Ctrl-y

Alt- - 2 Alt- Ctrl-y

现在你会看到:

$ echo ace

顺便说一句,您可以echo通过选择参数 0 将其放在线上:

Alt- 0 Alt- Ctrl-y

编辑:

要回答您添加到原件中的问题:

您可以按Alt-0然后反复按Alt-.逐步执行之前的命令 (arg 0)。同样Alt--然后重复Alt-.将允许您逐步完成之前的倒数第二个参数。

如果历史上的某一行没有合适的论据,就会敲响警钟。

如果您经常使用某个特定的组合,您可以定义一个宏,这样一键即可执行它。此示例将通过按Alt- Shift-从先前命令中调用第二个参数Y。您可以选择任何您喜欢的可用按键来代替这个按键。您可以反复按它以逐步浏览以前的内容。

要试用它,请在 Bash 提示符下输入宏:

bind '"\eY": "\e2\e."'

要使其持久化,请将此行添加到您的~/.inputrc文件中:

"\eY": "\e2\e."

不幸的是,这似乎不适用于 arg 0 或负参数数。

于 2010-10-24T20:04:06.713 回答
253

要使用第一个参数,您可以使用!^!:1

例子:

$ echo a b c d e 
a b c d e
$ echo !^
echo a
a

$ echo a b c d e 
a b c d e
$ echo !:1
echo a
a

由于您的问题是关于使用任何其他参数,因此这里有一些有用的参数:

!^      first argument
!$      last argument
!*      all arguments
!:2     second argument

!:2-3   second to third arguments
!:2-$   second to last arguments
!:2*    second to last arguments
!:2-    second to next to last arguments

!:0     the command
!!      repeat the previous line

前四种形式使用较多。这种形式!:2-有点违反直觉,因为它不包括最后一个参数。

于 2015-09-01T13:16:05.077 回答
62

我非常喜欢@larsmans 的回答,所以我必须了解更多。添加此答案以帮助其他人找到手册页部分并知道谷歌搜索的内容:

$ man  -P 'less -p ^HISTORY\ EXPANSION' bash
<...>
Word Designators

Word designators are used to select desired words from the event.
A : separates the event specification from the word designator.
It may be omitted if the word designator begins with a ^, $, *, -,
or %.  Words are numbered from the beginning of the line, with the
first word being denoted by 0 (zero).  Words are inserted into the
current line separated by single spaces.

   0 (zero)
          The zeroth word.  For the shell, this is the command word.
   n      The nth word.
   ^      The first argument.  That is, word 1.
   $      The last argument.
   %      The word matched by the most recent ‘?string?’ search.
   x-y    A range of words; ‘-y’ abbreviates ‘0-y’.
   *      All of the words but the zeroth.
          This is a synonym for ‘1-$’.  
          It is not an error to use * if there is just one word in
          the event; the empty string is returned in that case.
   x*     Abbreviates x-$.
   x-     Abbreviates x-$ like x*, but omits the last word.

   If a word designator is supplied without an event
   specification, the previous command is used as the event.
于 2014-07-10T09:18:40.013 回答
18

!^ 可能是第一个参数的命令。我不确定是否有办法获得第 n 个。

于 2010-10-24T17:26:11.147 回答
16

您还可以从历史记录中的任何命令中获取参数!


$ echo a b c d e f g
a b c d e f g
$ echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar
$ history | tail -5
  601  echo build/libs/jenkins-utils-all-0.1.jar
  602  history | tail -10
  603  echo a b c d e f g
  604  echo build/libs/jenkins-utils-all-0.1.jar
  605  history | tail -5
$ echo !-3:4
echo d
d
$ echo !604:1
echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar

于 2016-04-14T17:06:21.813 回答
11

在 Ubuntu 18.04 上测试


要插入先前的参数:

  • Alt+ .:插入最后一个命令的最后一个参数。
  • Alt+ #+ .:从最后一个命令插入#nth 最后一个参数。
  • Alt+ -, #, Alt+ ., zsh: Alt + -+ #+ .: 从最后一个命令中插入第 #n 个第一个参数。

在 Linux 中,您可以重复命令以返回历史记录

例子:

最后一个命令是:

mv foo bar
  • Alt+ 0+ .: 插入最后一个命令的第一个参数 =mv
  • Alt+ 2+ .: 插入最后一个命令的最后第二个参数 =foo
  • up, Ctrl+ w: 没有最后一个单词的最后一个命令 =mv foo

通用快捷方式

  • Ctrl+ w:从光标中删除最后一个单词
  • Alt+ d:从光标中删除下一个单词
  • Ctrl+ k:剪切光标后的所有内容
  • Ctrl+ u, zsh: Alt + w: 剪切光标前的所有内容
  • zsh: Ctrl + u: 剪切整个命令(在 bash 中你可以组合Ctrl+ u, Ctrl+ k
  • Ctrl+ y:粘贴之前用Ctrl+uCtrl+剪切的字符k
  • Ctrl+ _:撤消上次编辑(超过+时非常有用)Ctrlw
  • Ctrl+ left: 移到最后一个单词
  • Ctrl+ right: 移动到下一个单词
  • homeCtrl+ a:移动到行首
  • endCtrl+ e:移动到行尾

遍历上一个命令中的参数

仅适用于 zsh

运行或将其添加到您的~/.zshrc

autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[:" copy-earlier-word

现在使用Alt+.回到你想要的位置,然后使用Alt+:遍历参数

假设最后一个命令是

echo 1 2 3 4 5
  • Alt+ .:5
  • Alt+ .+ ::4
  • Alt+ .+ :+ ::3
  • Alt+ .+ :+ :+ :2
  • Alt+ .+ :+ :+ :+ :1
  • Alt+ .+ :+ :+ :+ :+ :echo

来源:https ://stackoverflow.com/a/34861762/3163120

查看所有可用的快捷方式

  • 重击: bind -lp
  • zsh: bindkey -L

我在这里保持最新状态:https ://github.com/madacol/docs/blob/master/bash-zsh_TerminalShorcuts.md

于 2019-03-08T19:32:56.063 回答
8

!^ 将为您获取第一个参数,!$ 将为您获取最后一个参数,!: n将为您获取第 n 个元素。

于 2018-11-05T22:01:03.597 回答
4

基本上,它可用于提取先前(命令的)参数

例如,如果发出以下命令:

echo Hello, world how are you today?

然后,Hello,将是第一个参数,today?第六,即最后一个;这意味着可以通过键入以下内容来引用它:

Alt+6其次是Ctrl-Alt-6


Ctrl传统上表示为^键名前面的帽子字符,并且是AltM eta前缀M-

所以上面的快捷方式可以重新定义为^Myyank。


此外,命令行中有帽子替换快捷方式:

echo Hello, world!

^Hello^Bye

Bye, world!

替换上一个命令的第一个匹配字符串,意思是:

Hello, world! Hello, people!

^Hello^Bye

会导致:

Bye, world! Hello, people!

保持第二场比赛 ( hello) 不变。

注意:帽子之间不要留空隙,否则操作将无法进行。


以上只是一个快捷方式:

!:s/Hello/Bye

event-level(*) 替换上一个命令中第一个找到的(匹配的)字符串,而在第一部分前面加上gswitch 将适用于整个行 g lobally

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

正如通常在其他相关命令中所做的那样sed,例如vi, 和 in regex(正则表达式) - 一种标准的搜索方式 (匹配字符串)。

不,你不能这样做,!:sg/Hello/Bye或者!:s/Hello/Bye/g在这里,这就是语法


  • !用于活动;事件可以理解为命令历史中的命令输出或操作。

这就是我自己使用它并从我从各种来源(包括手册页、博客和论坛)中阅读的内容中自己尝试的东西所理解的。

希望它能揭示一些神秘的方式bash,即 Bourne-Again shell(shell 上的一个游戏sh,它本身以其发明者的姓氏命名为 Bourne shell),在包括服务器(服务器操作系统)在内的许多发行版中是默认 shell。

于 2017-05-01T17:48:57.150 回答
1

接受答案末尾描述的方法也适用于我的第零个参数。我的中有这些行~/.inputrc

"\en": "\e0\e."
"\em": "\e1\e."
"\e,": "\e2\e."

\e2\e.\e2\e\C-y如果重复按下它而不是多次插入上一个命令的第二个参数,它的优势在于它会循环执行以前的命令。

要插入整个前面的命令,您可以键入!!\e^. \e^history-expand-line

于 2015-12-06T15:27:55.510 回答
0

如果你在 Mac 上,你会倾向于使用 ctrl+letter 获得扩展字符。我在终端(iTerm2)设置中将我的空格键选项键定义为元。这意味着我使用该键按单词导航并从以前的命令中提取参数。

于 2020-02-16T13:02:52.290 回答