【问题标题】:Can I have a shell alias evaluate a history substitution command?我可以让 shell 别名评估历史替换命令吗?
【发布时间】:2010-04-09 16:16:46
【问题描述】:

我正在尝试为 cd !!:1 编写一个别名,它采用前一个命令的第二个单词,并更改为该名称的目录。例如,如果我输入

rails new_project  
cd !!:1  

第二行将进入“new_project”目录。

由于 !!:1 打字很尴尬(即使它很短,它需要三个 SHIFTed 键,在键盘的相对两侧,然后是键入两次 SHIFTed 的键的未SHIFT版本),我想只需输入类似

的内容
cd-  

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

alias cd-=!!:1  

或者我会保存一个包含硬编码“new_project”的别名。所以我尝试了

alias cd-='!!:1'  

问题在于 !!:1 从未被评估过,并且我收到一条消息,指出不存在名为 !!:1 的目录。如何创建一个别名,在我发出别名命令时评估历史替换,而不是在我定义别名时,而不是从不?

(我在 bash 和 zsh 中都尝试过,并且在两者中都得到了相同的结果。)

【问题讨论】:

标签: bash history eval alias zsh


【解决方案1】:

对于 bash

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

【讨论】:

  • 在 bash 中非常好:谢谢!不幸的是,它在 zsh 中不起作用。 man history 和 history --help 没用,我无法通过谷歌搜索找到任何东西......有什么想法吗?
  • 我认为也有一种方法可以使用反引号。例如alias cd-='cd `!!:1`'。哪个更简洁(如果我能让它工作!)
  • @DGGenuine:反引号和 $() 运行命令;因此必须使用“history”内置函数。
【解决方案2】:

完成同样事情的另一种方法:

对于最后一个参数:

cd Alt-.

cd Esc .

对于第一个参数:

cd Alt-Ctrl-y

cd Esc Ctrl-y

【讨论】:

    【解决方案3】:

    对于 zsh:

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

    这是如何工作的:

    1. $(fc -l -1) 被评估。 fc -l {start} [{end}] 表示«列出从 {start} 到 {end} 的历史命令,如果 {end} 不存在,则为最后一个»。
    2. ${(z)...} 必须像 shell 一样将 ... 拆分为一个数组(参见 man zshexpn 中的 «参数扩展标志»),但实际上它拆分为空白。也许这只是我的错误。
    3. ${...[3]} 从数组中获取第三个值。第一个值是命令的编号,第二个是命令,第三个是参数。

    【讨论】:

    • 我刚刚做了类似的事情,最后得到了fc ... | cut -d' ' -f4-,它删除了命令的前导数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 2013-12-25
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多