如何使用上一个命令的参数?


287

我知道Esc+ .为您提供了最后一条命令的最后一个参数。

但是我对最后一个命令的第一个参数感兴趣。有按键绑定吗?

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

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

Answers:


284

就像M-.(meta-dot或esc-dot或alt-dot)是readline函数一样yank-last-argM-C-y(meta-control-y或esc-ctrl-y或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- .以逐步执行前面的命令(参数0)。类似地Alt- -然后重复Alt- .将允许您逐步浏览先前的倒数第二个参数。

如果历史上的某一行没有适当的论据,那么铃声将响起。

如果您经常使用特定的组合,则可以定义一个宏,以便一次击键即可执行。这个例子会按回想起以前的命令第二个参数Alt- - 。Shift Y您可以选择任何喜欢的可用击键来代替此击键。您可以反复按以逐步浏览以前的内容。

要进行尝试,请在Bash提示符下输入宏:

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

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

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

不幸的是,这似乎对arg 0或负参数号无效。


14
在寻找bash / readline的键盘快捷键时,我喜欢运行bind -lp并查看当前的绑定。
乍得·斯基特斯2014年

1
@ChadSkeeters:并且-s(Bash 4中的新增功能)列出了使用创建的宏-x
暂停,直到另行通知。

请注意,您也可以将digit参数与一起使用M-.Alt-3 Alt-Ctrl-y例如,等于hold Alt和input 3.。如果您3.多次键入该Alt命令而没有释放它,那么将遍历先前命令行的第三个参数。
甜点

@dessert:我在第二段中说了很多,然后举一个例子。
暂停,直到另行通知。

@ChadSkeeters,感谢您警告说将会有数百个条目!大声笑。
jdk1.0

308

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


115
!:3让你的第三个
马特道奇

108
!*让您大饱眼福
馄饨

74
!!获取整个命令。如果您忘记使用它很有用sudo
Un3qual

43
!:1-2除了3个论点中的最后一个之外,都能让您得到所有
Tyler Brock

5
只是警告一下-如果您使用组合参数,如echo foo{,bar} baz,该命令将记录为已打印并随后扩展。有了以上内容,使用echo !:1after解析为echo foo{,bar},然后扩展为echo foo foobar
Sean

200

要使用第一个参数,可以使用!^!: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-有点违反直觉,因为它不包含最后一个参数。


有没有办法获得倒数第二个物品?即file3mv file1 file2 file3 target/
查理·哈丁

3
我非常喜欢这个答案,并且出于完整性考虑,我建议还添加一行内容来说明“!-2”语法,该语法使您可以访问上一个命令之前的命令。
bbv

1
@bbv另外,为了更加完整,还可以使用命令“!2”访问历史记录中的第二个条目(如果仍然可用,取决于您的历史记录设置)。如果在每个提示中显示历史记录编号,则很有用。
816-8055 '19

53

我非常喜欢@larsmans的答案,所以我必须学习更多。添加此答案以帮助其他人找到手册页部分,并知道要为Google做什么:

$ 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.

18

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


7
上面建议的是!:n
Sergiu

有没有办法获得第n个最后一个项目(例如)!:n,但从头开始而不是从头开始计数?
查理·哈丁

14

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


$ 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


4

在Ubuntu 18.04上测试


要插入先前的参数:

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

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

例:

最后一个命令是:

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

一般捷径

  • Ctrl+ w:从光标中删除最后一个单词
  • Alt+ d:从光标中删除下一个单词
  • Ctrl+ k:光标后剪切所有内容
  • Ctrl+ uzsh: Alt + w:剪切光标之前的所有内容
  • zsh: Ctrl + u:剪切整个命令(在bash中,您可以组合Ctrl+ uCtrl+ k
  • Ctrl+ y:粘贴先前用Ctrl+ uCtrl+ 剪切的字符k
  • Ctrl+ _:撤消上一次编辑(超过Ctrl+ 时非常有用w
  • 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://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .上岩组在Mac上是打字🤔
安德烈·佩纳

1
退出 。有效,即使仅适用于最后一个。您无法继续输入以返回上一步。也许值得更新答案。非常感谢你。
安德烈·佩纳(

您可以bindkey -Lzsh中运行以查看绑定的所有快捷方式,也许它将有助于查明问题,甚至找到其他有用的命令。以我为例:绑定Alt .定义为bindkey "^[." insert-last-wordCtrl L(以清除屏幕)-> bindkey "^L" clear-screenAlt+Ctrl h-> bindkey "^[^H" backward-kill-word(与Ctrl w删除最后一个单词相同)
Madacol

@Madacol我还可以在绑定键上看到提到的复制早期单词,如 bindkey "^[^_" copy-prev-word
kikeenrique

3

基本上,它可以用于删除先前的(命令的)参数

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

echo Hello, world how are you today?

然后,Hello,将第一个参数,和today?所述第六,也就是最后一个; 表示可以通过键入以下内容进行引用:

Alt+6 其次是 Ctrl-Alt-6


Ctrl传统上将表示为^键名之前的帽子字符,Alt因为M-它是M eta前缀。

因此,可以将上述快捷方式重新定义为^My猛拉。


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

echo Hello, world!

^Hello^Bye

Bye, world!

替换上一个命令的第一个匹配字符串,表示:

Hello, world! Hello, people!

^Hello^Bye

会导致:

Bye, world! Hello, people!

保持第二个匹配(hello)不变。

注意:请勿在帽子之间留出空间,否则操作将无效。


以上只是以下方面的捷径:

!:s/Hello/Bye

使用event-level(*)替换上一条命令中找到的第一个(匹配)字符串,同时在第一部分加上g开关前缀将适用于整行 g lob

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

如通常被在其他相关的命令,例如完成sedvi以及在regex(正则表达式) -一个非标准的方法来搜索(匹配的字符串)。

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


  • !用于事件;事件可能被理解为命令输出或在命令历史记录中完成的操作。

这就是我自己使用它,并从包括手册页,博客和论坛在内的各种来源中尝试的东西上自己尝试的方式所了解的。

希望它能bash为Bourne-Again shell(一种在shshell上玩的游戏,在其发明人的姓氏后称其为Bourne shell)的神秘方式提供一些启发,这是许多发行版(包括服务器)(服务器OS)中的默认shell 。



0

在接受的答案结尾处描述的方法对我来说也适用于第零个参数。我在我的这些行~/.inputrc

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

\e2\e.优点\e2\e\C-y在于,如果反复按该命令,则会循环显示前一个命令,而不是多次插入前一个命令的第二个参数。

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


0

如果您使用的是Mac,则倾向于使用ctrl + letter获得扩展字符。我在我的终端机(iTerm2)中将我的空格键选项键定义为meta。这意味着我可以使用该键按字导航并从以前的命令中提取参数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.