使用bash历史记录获取上一个命令,将其复制然后“运行”,但命令已注释


79

只是一个提高我的bash技能的问题。我总是这样做:

$ history | grep some_long_command

...
...
123 some_long_command1.........
124 some_long_command2.........
...

然后,我可以通过执行以下命令运行命令:

!123

但是,我经常想这样做:

some_long_command1foobar

即在运行它之前更改命令。您可以使用bash代替运行此命令吗:

#some_long_command1

因此得到评论。

然后,我不必使用鼠标突出显示命令,对其进行编辑然后运行(我可以使用键盘-更快)。

我想我可以写一个脚本来做,但是可能已经在某处内置了功能……。


6
最简单的方法:bind Space:magic-space输入您的bash个人资料。然后,按Space将扩展!123some_long_command1
Blaz 2013年

@courteous:谢谢!那是我的新手。很有用。
marlar

Answers:


140

我建议不要使用history命令,而应使用ctrl+r并开始键入该命令。当您按箭头键进行修改时,它将退出自动完成识别,并让您在运行之前进行编辑。

更新:此外,如果您要循环浏览包含刚键入的字符串的不同命令,请继续按 ctrl+r


8
如果您使用vi键绑定(set -o vi),还可以使用它/来搜索历史记录并进行编辑。
William Pursell 2012年

1
一个更强大的功能是允许键入部分命令或命令中路径的一部分,然后使用箭头导航历史记录。搜索bash的向后搜索,向后搜索的选项
DavidC

2
DavidC,我已经看到其他人这样做了,但这对我不起作用。当我输入命令的前几个字母时,然后按向上箭头,它会忽略我正在输入的内容,并会浏览历史记录,好像我根本没有键入任何内容(最新到最旧)。您如何配置外壳来完成此任务?
丹尼尔·瓦特鲁斯

1
令人遗憾的是,向上/向下键不会在比赛中滚动,而是会立即退出搜索范围。我本来希望它向上/向下滚动显示匹配项(表明我仍在寻找我想要的命令),并且只向左/向右退出搜索(表明我已经找到了想要的命令)现在我可以对其进行编辑了)。
ADTC'3

3
@ADTC我刚刚找到一种执行您(和我)想要的方法的方法:按ctr+r,开始键入内容,然后在要查找包含该内容的所有命令时,只需按住即可ctrl+r。换句话说,您要进行上下移动的操作(以循环方式进行)是ctrl+r
Miquel 2014年

61

实际上,您可以仅附加:p到命令以打印它,而无需实际运行它。例如:

$ ls -la
$ !!:p

ls -la在不运行的情况下作为前一个命令打印输出,您只需按(向上)即可找到并编辑它。

你也可以

!123:p

以打印出第123rd条命令作为上一条命令。


2
+1最佳答案,因为它允许通常的历史记录命令回答OP :!mycmd:p。如果您在Bash中打开了vi命令,那么Pursell的答案将是一样的或更好的。如Miquel所述,Ctrl-r次之。
布伦特·浮士德

如果123 in不在行首,则可以执行以下操作:!?123?:p
Udi,

19

您也可以尝试fc使用命令在历史记录中编辑命令。

维基百科说,

FC是列表或编辑和重新执行,命令之前输入到一个交互式shell在Unix标准程序。fcbash shell中的内置 命令;help fc将显示使用情况信息。


除了反向增量搜索Ctrl+ R)外,我们还有更多bash快捷方式:

来自man bash

以前的历史(Cp)
    从历史记录列表中获取前一个命令,然后在列表中移回。 
下一历史(Cn)
    从历史记录列表中获取下一个命令,然后在列表中向前移动。 
历史的开始(M- <)
    移至历史记录的第一行。 
历史结束(M->)
    移至输入历史记录的末尾,即当前正在输入的行。 
反向搜索历史(Cr)
    从当前行开始向后搜索,并根据需要在历史记录中向上移动。这是一个增量搜索。
前向搜索历史(Cs)
    从当前行开始向前搜索,并根据需要在历史记录中“向下”移动。这是一个增量搜索。
非增量反向搜索历史(Mp)
    使用非增量搜索用户提供的字符串,从当前行开始向后搜索历史记录。 
非增量搜索历史(Mn)
    使用非增量搜索来搜索用户提供的字符串,以历史记录向前搜索。
yank-nth-arg(MCy)
    将第一个参数插入上一个命令(通常是前一行的第二个单词)。使用参数n插入上一个命令中的第n个单词(上一个命令中的单词以单词0开头)。负参数将插入上一个命令末尾的第n个单词。一旦计算出参数n,就如同已指定“!n”历史扩展名一样提取参数。
yank-last-arg(M-。,M-_)
    将上一个参数插入上一个命令(上一个历史记录条目的最后一个单词)。带有一个参数,其行为与yank-nth-arg完全相同。对yank-last-arg的连续调用将返回历史记录列表,依次插入每行的最后一个参数。历史扩展功能用于提取最后一个参数,就像已指定“!$”历史扩展一样。
外壳扩展线(MCe)
    像外壳一样展开线。这将执行别名和历史记录扩展以及所有shell单词扩展。有关历史记录扩展的说明,请参见下面的HISTORY EXPANSION。
历史记录扩展线(M- ^)
    在当前行执行历史记录扩展。有关历史记录扩展的说明,请参见下面的HISTORY EXPANSION。
插入最后一个参数(M-。,M-_)
    yank-last-arg的同义词。 
下一步操作并获得合作
    接受要执行的当前行,并从历史记录中获取相对于当前行的下一行以进行编辑。任何参数都将被忽略。
编辑并执行命令(C-xC-e)
    在当前命令行上调用编辑器,然后将结果作为shell命令执行。

11
!123:gs/old/new/

将运行命令123,将字符串“ old”替换为字符串“ new”。


6

您可以通过按M-^(在Mac上为Option-Shift-6)进入编辑模式。

输入:

!123M- ^

您将编辑命令#123。有点像使用ctrl-r,但是从感叹号语法开始。


可以M-^重新绑定到更友好的手指吗?
Blaz 2013年

4

无需使用history命令,而是将history-search-backward/绑定history-search-forward到可以轻松记住的快捷键(我更喜欢PgUp / PgDown)。为此,将其放入.inputrc文件中:

"<key code>":  history-search-backward
"<key code>":  history-search-forward

要获得<key code>,类型Ctrl-V <key>的外壳,并更换起动^[\e在什么是输出。

设置完成后,您只需键入some并按PgUp即可some_long_command。如果需要,some_long_command with_some_argsome_long_command with_some_other_arg在历史记录的后面有类似的命令,您可以循环浏览直到通过some反复键入然后再次击中PgUp到达它为止,或者可以键入some,击中PgUp并将光标移至两个命令开始不同的位置,输入几个字符,然后再次点击PgUp。在我看来,这种快速翻阅/区分相似命令的能力使它成为比Ctrl-R


3

你也可以放

shopt -s histverify

在您的中.bash_profile,这会导致任何历史扩展在不运行的情况下显示在命令行中,从而允许您在执行操作之前进行编辑。




0

别名r ='fc -s'

.bashrc(主目录)中输入

r <whatever>

在命令提示符处,您将执行<whatever>历史记录中的最后一个命令(相同的参数)的副本。如果需要,只需按向上箭头查看执行的操作。

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.