我已经使用 bash 自动完成功能一段时间了,但找不到解决问题的方法。我有一个项目目录,其中包含如下子文件夹:
- 项目/ruby/project1
- 项目/ruby/project2
- 项目/rails/project3
- 项目/html/project4
现在我想要一个命令,cdproject
可以cd
在我的项目目录和子目录中的任何子文件夹中调用它。并且此命令应提供自动完成功能,我可以在其中键入cdproject pr --> TAB TAB
然后获取一个列表,例如ruby/project1
,,...ruby/project2
rails/project3
我的问题是如何处理子目录。程序cdproject
如下所示
#!/bin/bash
cd $1
看起来cdproject-autocompletion.bash
像这样
_cdproject()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts=$(ls ~/Dropbox/projects)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -o default -o nospace -F _o o
在我的里面.bash_profile
我已经找到cdproject-autocompletion.bash
了
source ~/cdproject-autocompletion.bash
那么有人知道该如何实现吗?也许应该opts
返回子目录结构ruby/project1
,但自动完成功能应该只对最后一部分(即实际项目名称)起作用。我不知道这是如何实现的。
答案1
深入阅读这个问题,您正在寻找从命令行浏览文件树的更流畅的方法。
选项 1:使用CDPATH
例如, CDPATH=".:~:~/projects/ruby:~/projects/rail:~/projects/html"
†
注意:有些人认为包含以下内容很有用..
在CDPATH
。
不幸的是,‡CDPATH
并不(总是)支持自动完成。有多种方法可以扩展 bash 来实现这一点。使用术语“CDPATH”和“自动完成”在 Google 上搜索。
不可否认,这有点笨重。如果您使用的父目录数量很少,那么这还不算太糟。
您可能更适合使用dirs
、pushd
和popd
。这些需要花些时间才能掌握。请注意pushd
和popd
可以采用数字参数。
另外:
cd -
返回上一个目录。重复该命令可在两个最近的目录之间切换。____________
†
许多文档(包括手册页)显示.
(点;即当前目录)作为 中的一个组成部分CDPATH
。然而,至少有些 shell 似乎认为CDPATH
以:.
,所以,如果你说cd foo
,你将得到,./foo
除非你列出的其他父目录CDPATH
包含foo
。YMMV。
‡编者注:Cygwin 似乎支持CDPATH
开箱即用的自动完成功能(运行 bash 版本“4.1.17(9)-release”)。
答案2
这看起来非常复杂,但这是我想出的解决方案:
函数 gcd { cd $HOME/git/firefly/$1 } 函数 _gcdcomplete() { 本地命令 curb cur 选择 # 基本目录 git=$HOME/git/firefly/ # 到目前为止的最后一个参数 cur="${COMP_WORDS[COMP_CWORD]}" # dirname-esque,但是使 "xyz/" => "xyz/" 而不是 "." curb=$(echo $cur | sed 's,[^/]*$,,') # 获取目录列表(使用注释行列出目录和文件) # 将“/”附加到目录 # cmd="find $git$curb -maxdepth 1 -type d -printf %p/\n , -type f -print " cmd="查找$git$curb -maxdepth 1 -type d -printf %p/\n" # 从列表中删除基本目录并删除多余的尾随 /s opts=$($cmd | sed s:$git:: | sed s://*$:/:) # 生成完成列表 COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) 返回0; } 完成 -o 无空间 -F _gcdcomplete gcd