我能否使用shell别名来执行历史替换命令?

6

我想要为cd !!:1写一个别名,它将获取上一条命令的第二个单词,并切换到该名称的目录。例如,如果我输入:

rails new_project  
cd !!:1  

第二行将进入“new_project”目录。由于!!:1难以输入(即使它很短,也需要键盘两侧的三个SHIFT键和一个未按下SHIFT键的重复按下的键),因此我想只输入类似于
cd-  

但是由于!!:1是在命令行上被评估的,所以我(显然)不能只是这样做

alias cd-=!!:1  

或者我将保存一个包含“new_project”硬编码的别名。因此,我尝试了:
alias cd-='!!:1'  

这个问题在于 !!:1 从未被评估,我收到了一个消息,说没有名为 !!:1 的目录存在。我该如何创建一个别名,在我发出别名命令时评估历史替换,而不是在定义别名时或从不评估?(我已经在 bash 和 zsh 中尝试过,结果都一样。)

可能在Unix上相同:http://unix.stackexchange.com/questions/85352/how-can-i-alias-sudo/85354 - Ciro Santilli OurBigBook.com
3个回答

9

对于 bash

alias cd-='cd $(history -p !!:1)'

在bash中非常好:谢谢!但是在zsh中不起作用。man history和history --help都没用,我也无法通过Google找到任何东西...有什么想法吗? - iconoclast
我认为也可以使用反引号来实现这个功能,例如:alias cd-='cd \!!:1`'`。如果我能让它工作的话,这种方法会更加简洁。 - Carl G
1
@DGGenuine:反引号和$() 运行命令;因此必须使用“history”内置命令。 - Teddy

8

另一种实现相同功能的方法:

对于最后一个参数:

cd Alt-.

或者

cd Esc .

对于第一个参数:

cd Alt-Ctrl-y

或者

cd Esc Ctrl-y


7

对于zsh:

alias cd-='cd ${${(z)$(fc -l -1)}[3]}'

工作原理:

  1. 评估$(fc -l -1)fc -l {start} [{end}]的意思是“列出从{start}到{end}或最后一个命令的历史命令”。
  2. ${(z)...}必须像shell一样将...拆分为数组(请参见man zshexpn中的“参数扩展标志”),但实际上它是在空格上拆分的。也许这只是我的错误。
  3. ${...[3]}从数组中取第三个值。第一个值是命令的编号,第二个是命令,第三个及以后是参数。

我刚刚做了类似的事情,最终得到了 fc ... | cut -d' ' -f4-,它可以去掉命令前面的数字。 - Steven Lu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接