如何在zsh命令中引用路径尾部的根?

用户938271

我经常克隆git存储库,然后进入其根目录。例如:

$ git clone https://github.com/hpjansson/chafa && cd chafa

为了使它更容易一些,我有一个zsh缩写– cc–扩展为&& cd !#:2:t

typeset -Ag abbrev
abbrev=(
  'G' '| grep -v grep | grep'
  'L' '2>&1 | less'
  'V' '2>&1 | vipe >/dev/null'
  'ac' '| column -t'
  'bl' '; tput bel'
  'cc' '&& cd !#:2:t'
  'fl' "| awk '{ print $"
  'ne' '2>/dev/null'
  'pf' "printf -- '"
  'sl' '>/dev/null 2>&1'
  'tl' '| tail -20'
)
__abbrev_expand() {
  emulate -L zsh
  setopt EXTENDED_GLOB
  local MATCH
  LBUFFER=${LBUFFER%%(#m)[a-zA-Z]#}
  if [[ "${LBUFFER: -1}" == ' ' ]]; then
    LBUFFER+=${abbrev[$MATCH]:-$MATCH}
    if [[ $MATCH = 'fl' ]]; then
      RBUFFER="}'"
    elif [[ $MATCH = 'pf' ]]; then
      RBUFFER="\n'"
    fi
  else
    LBUFFER+=$MATCH
  fi
  zle self-insert
}
zle -N __abbrev_expand
bindkey ' ' __abbrev_expand
bindkey -M isearch ' ' self-insert

!#指的是当前命令行,如man zshexpn(小节HISTORY EXPANSION,小节Event Designators)所述:

!#请参考到目前为止键入的当前命令行。该行被视为已完成,直到该行包含!#参考号之前的单词

:2指的是命令行中的第二个单词(当我键入$ git clone命令时是URL ):

n 第n个参数。

:t指代该词的尾部:

t删除所有前导路径名组件,保留结尾。这就像basename


通常,我将git clone在命令行上键入,然后复制粘贴项目的url,然后插入一个空格cc和另一个空格,以提供所需的命令。

但是,有时,我复制粘贴的URL以extension结尾.git当发生这种情况时,的扩展!#:2:t包含不希望的.git扩展:

$ git clone https://github.com/hpjansson/chafa.git cc
→
$ git clone https://github.com/hpjansson/chafa.git && cd !#:2:t
→
$ git clone https://github.com/hpjansson/chafa.git && cd chafa.git
cd: no such file or directory: chafa.git

一种解决方案是还使用:r修饰符删除.git扩展名:

r删除保留根名称的文件扩展名。没有文件扩展名的字符串不会更改。文件名扩展名.后跟任意数量的字符(包括零),既不是也不./,并且一直持续到字符串的末尾。例如,扩展名为foo.orig.cis .cdir.c/foo没有扩展名。

                                                               vv
$ git clone https://github.com/hpjansson/chafa.git && cd !#:2:t:r
→
$ git clone https://github.com/hpjansson/chafa.git && cd chafa

但是,如果路径不以.git扩展名结尾,则扩展将失败,并且git命令和cd命令均不会执行。

这是一个说明问题的最小示例:

$ echo /foo/bar.baz !#:1:t:r
/foo/bar.baz bar

$ echo /foo/bar !#:1:t:r
zsh: modifier failed: r

第一条命令成功,因为最后一个路径组件包含extension .baz,但是第二条命令失败,因为不再有扩展名。OTOH,在bash中4.3.48,两个命令均按预期工作。

我不明白为什么:r没有扩展名时会失败,因为其文档中包含以下语句:

没有文件扩展名的字符串不会更改。

它不是说:r对不包含扩展名的字符串使用是错误的。


我尝试了另一种方法;使用:s修饰符删除扩展名我认为这需要设置HIST_SUBST_PATTERN选项:

setopt HIST_SUBST_PATTERN

使用此选项,可以编写:s/.*删除扩展的代码:

                          vvvvv
$ echo /foo/bar.baz !#:1:t:s/.*
/foo/bar.baz bar

有扩展名时,它可以工作,但没有扩展名时,它又会失败:

$ setopt HIST_SUBST_PATTERN
$ echo /foo/bar !#:1:t:s/.*
zsh: substitution failed

是否有单个修饰语序列可以同时引用barin/foo/bar.bazbarin /foo/bar

我正在使用zsh 5.7.1-dev-0 (x86_64-pc-linux-gnu)

吉勒斯“别再邪恶了”

我想不出一种通过历史扩展来做到这一点的方法。但是我不认为历史扩展是这里最好的工具。这是非常有限的。zle小部件中,您可以访问命令行并使用任意代码对其进行操作。利用这一点。

一种方法是对缩写进行扩展:而不是$abbrev[$MATCH]使用${(e)abbrev[$MATCH]}显然,您需要更改您的缩写以适当地引用特殊字符。对于cc,请使用类似

&& cd ${${(z)BUFFER}[3]}

对于的特定情况git clone,更一般而言,对于在当前目录中创建目录的任何内容,可以使用不同的缩写:切换到新创建的目录。这适用于git clone https://example.com/foo.git,forgit clone https://example.com/foo和forgit clone https://example.com/foo.git bar以及for tar xf foo.tar(如果归档文件具有单个顶级目录)和mv /some/directory .

&& cd *(/oc[1])

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在 Flask 中“回到根路径”?

如何在Symfony 4 Console命令中获取应用程序根路径

ZSH如何解释命令用作路径的变量中的通配符

如何在jar中配置Maven:assembly根路径

如何在代码中获取Eclipse根路径?

如何在根网址(/-无路径)中运行FastCGI脚本?

如何在ApiGateway中获取根资源的资源路径?

如何在PHP中获得对根对象的迭代对象引用?

如何在 UITableViewCell 中截断 UILabel 的尾部

尾部如何在链接的结构中工作?

如何在zsh中获得命令的执行毫秒时间?

如何在命令行中创建永久的 zsh 别名?

如何在VSTS VsTest任务中引用coverage文件路径?

Flask路径中的尾部斜杠

如何在MYSQL中编写“命令的最短路径”或至少“查找路径”的命令?

如何在python中为环境路径复制eval命令?

如何在确定的路径中执行git命令?

如何在vbscript中以变量作为路径执行命令

如何在sh命令中引用groovy变量

如何在awk命令中按名称引用列?

如何在Windows上的“ for / F”循环命令中引用空格

如何在 sum 命令中引用您所在的工作表

如何在Zsh中使用“源”命令

Zsh:如何在命令后自动完成?

如何配置 IIS 以在没有尾部斜杠的情况下提供目录并始终相对于根路径提供服务?

用于XML路径时如何在根元素中添加属性值?

如何在jstree中获取选定节点的完整路径?(从根节点到选定节点)

如何在Java EE中获取Web项目的根路径

如何在规则表达式中引用数据库的 NEW 根?