我试图在bash脚本中自动填充文件夹名称.如果我输入完整的文件夹名称一切正常,但我不知道如何自动完成名称.有任何想法吗?
repo() {
cd ~/Desktop/_REPOS/$1
}
Run Code Online (Sandbox Code Playgroud)
我试着阅读这篇SO帖子的想法,但很快就迷路了,因为我还是很吵.
GOAL(上面的repo函数包含在我的bashrc中):
>ls ~/Desktop/_REPOS/
folder1
hellofolder
stackstuff
>repo sta[TAB] fills in as: repo stackstuff
Run Code Online (Sandbox Code Playgroud)
实际上你可以从geirha的答案中借用相当多的代码:
# this is a custom function that provides matches for the bash autocompletion
_repo_complete() {
local file
# iterate all files in a directory that start with our search string
for file in ~/Desktop/_REPOS/"$2"*; do
# If the glob doesn't match, we'll get the glob itself, so make sure
# we have an existing file. This check also skips entries
# that are not a directory
[[ -d $file ]] || continue
# add the file without the ~/Desktop/_REPOS/ prefix to the list of
# autocomplete suggestions
COMPREPLY+=( $(basename "$file") )
done
}
# this line registers our custom autocompletion function to be invoked
# when completing arguments to the repo command
complete -F _repo_complete repo
Run Code Online (Sandbox Code Playgroud)
该for循环遍历目录中,在给定的第二个参数字符串开头的所有文件_repo_complete的功能(这是要自动完成的字符串).
添加代码到你的.bashrc,它应该工作!
cd如果我理解正确的话,我会看到两个选项来获得你想要的东西,即自定义命令的路径自动完成.
您可以将父目录添加~/Desktop/_REPOS到CDPATH环境变量中:
CDPATH="$CDPATH":"$HOME"/Desktop/_REPOS
Run Code Online (Sandbox Code Playgroud)
现在,您可以从任何目录中键入cd SpaceTab,除了当前目录的子目录外,~/Desktop/_REPOS还将显示所有目录.(这也是这种方法的缺点:更加混乱.)
您可以添加完成功能.bashrc.你开始的方式,你想要所有目录的基本名称~/Desktop/_REPOS.要获得目录的自动完成,我们可以使用compgen -d内置:
$ compgen -d "$HOME"/Desktop/_REPOS/
/home/me/Desktop/_REPOS/folder1
/home/me/Desktop/_REPOS/folder2
/home/me/Desktop/_REPOS/stackstuff
/home/me/Desktop/_REPOS/hellofolder
Run Code Online (Sandbox Code Playgroud)
这将返回所有子目录的名称.当路径更具体时,它减少到更少的候选者:
$ compgen -d "$HOME"/Desktop/_REPOS/f
/home/me/Desktop/_REPOS/folder1
/home/me/Desktop/_REPOS/folder2
Run Code Online (Sandbox Code Playgroud)
要删除除基本名称之外的所有内容,我们使用shell参数扩展,如下所示:
$ arr=(/path/to/dir1 /path/to/dir2)
$ echo "${arr[@]##*/}"
dir1 dir2
Run Code Online (Sandbox Code Playgroud)
##*/在参数扩展中删除了*/每个元素的最长匹配arr,即,只留下最后一个正斜杠之后的内容 - 正是我们想要的.
现在我们将它们组合在一起并形成一个函数:
_comp_repo () {
# Get list of directories
# $2 is the word being completed
COMPREPLY=($(compgen -d "$HOME"/Desktop/_REPOS/"$2"))
# Reduce to basenames
COMPREPLY=("${COMPREPLY[@]##*/}")
}
Run Code Online (Sandbox Code Playgroud)
这与您.bashrc使用它的指令一起进入自动完成repo:
complete -F _comp_repo repo
Run Code Online (Sandbox Code Playgroud)
请注意,您的repo函数应引用$1参数以确保它正确处理具有特殊字符(空格,制表符...)的目录名称:
repo () {
cd ~/Desktop/_REPOS/"$1"
}
Run Code Online (Sandbox Code Playgroud)您击中的次数Tab取决于读取线设置,例如show-all-if-ambiguous.
参考