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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4009412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:48:25  来源:igfitidea点击:

How to use arguments from previous command?

bashcommand-linekeyboard-shortcutsinput-history

提问by Aman Jain

I know that Esc+ .gives you the last argument of the last command.

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

But I'm interested in first argument of the last command. Is there a key binding to do so?

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

On the same lines, is there a generic way of getting the nth argument from the last command? I know that in a bash script, you can use $0, $1etc., but these don't work on the commandline.

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

Also, what about iterating through the 0th argument of previous commands, like we can do with the last argument by continuously pressing Esc+ .?

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

采纳答案by Paused until further notice.

Just as M-.(meta-dot or esc-dot or alt-dot) is the readline function yank-last-arg, M-C-y(meta-control-y or esc-ctrl-y or ctrl-alt-y) is the readline function yank-nth-arg. Without specifying n, it yanks the first argument of the previous command.

正如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,它会拉取上一个命令的第一个参数。

To specify an argument, press Escape and a number or hold Alt and press a number. You can do Alt--to begin specifying a negative number then release Alt and press the digit (this will count from the end of the list of arguments.

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

Example:

例子:

Enter the following command

输入以下命令

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

Now at the next prompt, type echo(with a following space), then

现在在下一个提示下,键入echo(带有以下空格),然后

Press Alt-Ctrl-yand you'll now see:

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

$ echo a

without pressing Enteryet, do the following

不按Enter,请执行以下操作

Press Alt-3Alt-Ctrl-y

Alt- 3Alt- Ctrl-y

Press Alt--2Alt-Ctrl-y

Alt- -2Alt- Ctrl-y

Now you will see:

现在你会看到:

$ echo ace

By the way, you could have put the echoon the line by selecting argument 0:

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

Press Alt-0Alt-Ctrl-y

Alt- 0Alt- Ctrl-y

Edit:

编辑:

To answer the question you added to your original:

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

You can press Alt-0then repeatedly press Alt-.to step through the previous commands (arg 0). Similarly Alt--then repeating Alt-.would allow you to step through the previous next-to-last arguments.

您可以按Alt-0然后重复按Alt-.以逐步执行先前的命令 (arg 0)。类似地Alt--然后重复Alt-.将允许您逐步完成前一个倒数第二个参数。

If there is no appropriate argument on a particular line in history, the bell will be rung.

如果在历史上的特定路线上没有适当的论据,就会敲响警钟。

If there is a particular combination you use frequently, you can define a macro so one keystroke will perform it. This example will recall the second argument from previous commands by pressing Alt-Shift-Y. You could choose any available keystroke you prefer instead of this one. You can press it repeatedly to step through previous ones.

如果有您经常使用的特定组合,您可以定义一个宏,以便一次按键即可执行。此示例将通过按Alt- Shift-调用先前命令中的第二个参数Y。您可以选择任何您喜欢的可用按键而不是这个按键。您可以反复按它来浏览以前的。

To try it out, enter the macro at a Bash prompt:

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

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

To make it persistent, add this line to your ~/.inputrcfile:

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

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

Unfortunately, this doesn't seem to work for arg 0 or negative argument numbers.

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

回答by user1953081

!$gets the last element of the previous command line argument.

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

回答by nonopolarity

To use the first argument, you can use !^or !:1

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

Example:

例子:

$ 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

Since your question is about using any other arguments, here are some useful ones:

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

!^      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

The first four forms are more often used. The form !:2-is somewhat counter-intuitive, as it doesn't include the last argument.

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

回答by Ajith Antony

I liked @larsmans answer so much I had to learn more. Adding this answer to help others find the man page section and know what to google for:

我非常喜欢@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.

回答by Orbit

!^ may be the command for the first argument. i'm not sure if there is a way to get the nth.

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

回答by GuyMatz

You can also get arguments from any command in your history!

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


$ 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

回答by Madacol

Tested on Ubuntu 18.04

在 Ubuntu 18.04 上测试



To insert previous arguments:

要插入先前的参数:

  • Alt+.: insert last argument from last command.
  • Alt+#+.: insert #nth last argument from last command.
  • Alt+-, #, Alt+., zsh:Alt+-+#+.: insert #nth first argument from last command.
  • Alt+ .:插入最后一个命令的最后一个参数。
  • Alt+ #+ .: 从最后一个命令插入 #nth 最后一个参数。
  • Alt+ -, #, Alt+ ., zsh:Alt+ -+ #+ .: 从最后一个命令插入第 #n 个参数。

In Linux you can repeat commands to go back in history

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

Example:

例子:

Last command is:

最后一条命令是:

mv foo bar
  • Alt+0+.: insert first argument of last command = mv
  • Alt+2+.: insert last 2nd argument of last command = foo
  • up, Ctrl+w: last command without the last word = mv foo
  • Alt+ 0+ .: 插入最后一个命令的第一个参数 =mv
  • Alt+ 2+ .:插入最后一个命令的最后一个第二个参数 =foo
  • up, Ctrl+ w: 没有最后一个字的最后一个命令 =mv foo

General shortcuts

一般快捷键

  • Ctrl+w: removes last word from cursor
  • Alt+d: removes next word from cursor
  • Ctrl+k: cuts everything after cursor
  • Ctrl+u, zsh:Alt+w: cuts everything before cursor
  • zsh:Ctrl+u: cuts the entire command (In bash you can combine Ctrl+u, Ctrl+k)
  • Ctrl+y: paste characters previously cut with Ctrl+uand Ctrl+k
  • Ctrl+_: undo last edit (very useful when exceeding Ctrl+w)
  • Ctrl+left: move to last word
  • Ctrl+right: move to next word
  • homeor Ctrl+a: move to start of line
  • endor Ctrl+e: move to end of line
  • 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+ _:撤消上次编辑(超过Ctrl+时非常有用w
  • Ctrl+ left: 移到最后一个字
  • Ctrl+ right: 移动到下一个单词
  • homeCtrl+ a: 移至行首
  • endCtrl+ e: 移至行尾

To iterate through the arguments in a previous command

遍历上一个命令中的参数

only works in zsh

仅适用于 zsh

run or add this to your ~/.zshrc

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

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

Now use Alt+.to go as back as you want, then use Alt+:to iterate through the arguments

现在使用Alt+.返回任意值,然后使用Alt+:遍历参数

Assuming last command is

假设最后一个命令是

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

source: https://stackoverflow.com/a/34861762/3163120

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

To see all shortcuts available

查看所有可用的快捷方式

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


I'm keeping this up-to-date in this gist https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9

我在这个要点中保持最新状态https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9

回答by Madacol

Basically it has a use in yanking previous(command's) arguments.

基本上它在 yanking之前的(command's) arguments 中有一个用处。

For instance, if the following command is issued:

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

echo Hello, world how are you today?

then, Hello,will be the first argument, and today?the sixth, that is the last one; meaning it can be referenced by typing:

然后,Hello,将第一个参数,和today?所述第六,也就是最后一个; 这意味着它可以通过键入来引用:

Alt+6followed by Ctrl-Alt-6

Alt+6其次是 Ctrl-Alt-6



Ctrlis traditionally denoted as a hat character ^prepended to keys names, and Altas M-that is Metaprefix.

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

So the above shortcut can be redefined as ^Myto yank.

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



Also, there is hatssubstitution shortcut in the command line:

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

echo Hello, world!

^Hello^Bye

Bye, world!

to substitute the previous command's first matched string, meaning:

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

Hello, world! Hello, people!

^Hello^Bye

would result in:

会导致:

Bye, world! Hello, people!

leaving the second match (hello) unchanged.

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

Note: Do not leave space between hats, or the operation won't work.

注意:帽子之间不要留空隙,否则操作无效。



The above is just a shortcut for:

以上只是一个快捷方式:

!:s/Hello/Bye

event-level(*) substitution for the first found (matched) string in the previous command, while prefixing the first part with the gswitch will apply to the whole lineglobally:

事件级(*)代替前一命令的第一值(匹配的)字符串,而与所述前缀的第一部分g开关将适用于整个线lobally

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

as usually being done in other related commands such as sed, vi, and in regex(regular expression) - a standart way to search (match string).

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

No, you can't do !:sg/Hello/Byeor !:s/Hello/Bye/ghere, that's the syntax!

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



  • ! is for events; event might be understood as command output or operation done in the commands history.
  • !用于事件;事件可以理解为命令历史中的命令输出或操作。


That's what I understood by using it myself and trying things on my own from what I read from various sources including manual pages, blogs, and forums.

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

Hope it will shed some light into mysterious ways of bash, the Bourne-Again shell (a play on shshell, which itself is called Bourne shell after its inventor's last name), what is default shell in many distributions including servers (server OS's).

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

回答by Moshe Bixenshpaner

!^ will get you the first param, !$ will get you the last param, !:nwill get you the nth element.

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

回答by nisetama

The method described at the end of the accepted answer also works with the zeroth argument for me. I have these lines in my ~/.inputrc:

接受的答案末尾描述的方法也适用于我的第零个参数。我在我的以下几行~/.inputrc

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

\e2\e.has the advantage over \e2\e\C-ythat it cycles through previous commands if it is pressed repeatedly instead of inserting the second argument of the previous command multiple times.

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

To insert the whole previous command, you can type !!\e^. \e^is history-expand-line.

要插入整个上一个命令,您可以输入!!\e^. \e^history-expand-line