如何使“cd ...”分组两个目录?

如何使“cd ...”分组两个目录?

因此,目前在 macOS 上我设置了如下别名...

alias ...='cd ../..'
alias ....='cd ../../..'

...这样我就可以通过在终端中输入来进入多个目录。但是,在我之前的设置中,输入cd ...会进入多个目录。我cd一开始就被训练过如何书写……我该如何更改我的别名才能让它按照我想要的方式工作?

答案1

在...的帮助下https://stackoverflow.com/questions/941338/how-to-pass-command-line-arguments-to-a-shell-alias你的问题可以这样解决:

alias cd='function _cd(){ cd ${1/.../..\/..}; }; _cd '

函数中的参数扩展将所有出现的“...”替换为“../..”,因此这不是一个真正干净的解决方案,但我认为它仍然可以接受或可以改进。

答案2

别名不能包含空格。要使用别名执行所需操作,您需要利用此属性:

如果替换单词的别名值以 <blank> 结尾,则 shell 应检查下一个命令字以进行别名替换;此过程应持续,直到找到不是有效别名的单词或别名值不以 <blank> 结尾。

来源), 所以cd 连续...被解析为别名。

您需要这样的别名:

cd='cd '
...='../..'
....='../../..'
# and so on

但是如果你碰巧有一个名为 的目录ls,并且你输入cd ls,那么ls也容易发生别名替换。如果ls是别名,这将适得其反。

因此,纯别名方法是错误的。此函数将执行(用它没有上述别名):

cd() {
       if [ "$#" -eq 0 ]; then
          command cd
       elif [ "$(printf '%s' "$1" | wc -l)" -eq 0 ]; then
          command cd "$(printf '%s' "$1" | sed '/^\.\.\+$/ {s|..|.|; s|.|../|g }')";
       else
          command cd "$1"
       fi
     }

(注意:为了使其在 中工作zsh,请在函数体中调用set -o POSIX_BUILTINS或替换每个command) 。builtin

sed获取传递给函数的参数,并且当且仅当它由两个或多个点组成时才更改它;该工具会删除第一个点并用替换每个点(剩下的)../

还有额外的逻辑:

  • [ "$#" -eq 0 ]允许鞋底cd(无参数)正常工作。
  • [ "$(printf '%s' "$1" | wc -l)" -eq 0 ]是为了防止sed改变多行目录名称(foo<newline>.....例如有效名称)。请注意,对于通常的名称(不包含换行符),wc -l将返回0(不是1,POSIX 不认为没有以换行符结尾的“行”是行),因此我们针对进行测试0

还有一个怪癖:

  • s|..|.|两个点不是文字点,这是正则表达式。有人可能会说应该是,s|\.\.|.|但请注意/^\.\.\+$/确保行中首先只有点。这同样适用于中的第一个点s|.|../|g

相关内容