我正在尝试在bash脚本中自动填充文件夹名称。如果我输入完整的文件夹名称一切正常,但我不知道如何自动完成名称。有什么想法吗?
repo() {
cd ~/Desktop/_REPOS/$1
}
我试着阅读this SO post的想法,但很快就迷失了,因为我仍然很吵。但
GOAL(上面的repo函数包含在我的bashrc中):
>ls ~/Desktop/_REPOS/
folder1
hellofolder
stackstuff
>repo sta[TAB] fills in as: repo stackstuff
答案 0 :(得分:8)
实际上你可以从geirha's answer借用相当多的代码:
# 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
for
循环遍历目录中的所有文件,这些文件以作为_repo_complete
函数的第二个参数给出的字符串开头(这是要自动完成的字符串)。
将代码添加到.bashrc
,它应该可以使用!
答案 1 :(得分:8)
如果我理解正确的话,我会看到两个选项来获取您想要的内容,即自定义cd
命令的路径自动完成。
您可以将父目录~/Desktop/_REPOS
添加到CDPATH
环境变量中:
CDPATH="$CDPATH":"$HOME"/Desktop/_REPOS
现在,在任何目录中,您都可以键入cd
Space Tab ,除了当前目录的子目录外,还可以输入{的所有目录{1}}会出现。 (这也是这种方法的缺点:更加混乱。)
您可以为~/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
要删除除基本名称之外的所有内容,我们使用shell参数扩展,如下所示:
$ compgen -d "$HOME"/Desktop/_REPOS/f
/home/me/Desktop/_REPOS/folder1
/home/me/Desktop/_REPOS/folder2
参数展开中的 $ arr=(/path/to/dir1 /path/to/dir2)
$ echo "${arr[@]##*/}"
dir1 dir2
会从##*/
的每个元素中移除*/
的最长匹配,即,只留下最后一个正斜杠之后的内容 - 恰好是什么我们想要。
现在我们把它放在一起,放到一个函数中:
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[@]##*/}")
}
,以及使用.bashrc
自动完成的说明:
repo
请注意,您的complete -F _comp_repo repo
函数应引用repo
参数,以确保它正确处理带有特殊字符(空格,制表符...)的目录名称:
$1
您点击标签的次数取决于readline settings,例如repo () {
cd ~/Desktop/_REPOS/"$1"
}
。
<强>参考强>