有没有一种方法可以指定特定命令不区分大小写,而不需要全局打开不区分大小写(至少对于那个 shell)?
在我的特殊情况下,我有一个小应用程序,可以让我通过命令行访问电子邮件地址数据库,所以我输入:
db get email john smith
它返回 John Smith 的电子邮件地址。所以我设法在应用程序内部实现了主要的完成:设置
COMPREPLY=($(compgen -W "$(db --complete $COMP_CWORD "$COMP_WORDS[@]"}")" -- ${COMP_WORDS[COMP_CWORD]}))
允许我使用制表符完成 get
和 email
.但是,如果我然后键入 j<tab>
, 它拒绝了,因为在电子邮件数据库中,它被正确地大写了。无论如何,我想让 bash 完成它。 (如果我使用大写字母 J
,它会起作用。)
否则,我可以得到我的 --complete
选项通过匹配输入来更改其回复的大小写,我想,但理想情况下命令行会尽可能匹配数据库。
请注意,我在使用 readline 时在应用程序内部进行了此操作,它仅与 bash 交互,这似乎是一个问题。
最佳答案
确实,似乎没有办法让 compgen
对单词列表 (-W
) 进行不区分大小写的匹配。
我看到以下解决方法:
简单的解决方案:首先将单词列表和输入标记都翻译成全小写。 注意:仅这是一个可以接受将所有补全变成全小写的选项。
complete_lower() {
local token=${COMP_WORDS[$COMP_CWORD]}
local words=$( db --complete $COMP_CWORD "${COMP_WORDS[@]}" )
# Translate both the word list and the token to all-lowercase.
local wordsLower=$( printf %s "$words" | tr [:upper:] [:lower:] )
local tokenLower=$( printf %s "$token" | tr [:upper:] [:lower:] )
COMPREPLY=($(compgen -W "$wordsLower" -- "$tokenLower"))
}
更好但更精细的解决方案:推出您自己的不区分大小写的匹配逻辑:
complete_custommatch() {
local token=${COMP_WORDS[$COMP_CWORD]}
local words=$( db --complete $COMP_CWORD "${COMP_WORDS[@]}" )
# Turn case-insensitive matching temporarily on, if necessary.
local nocasematchWasOff=0
shopt nocasematch >/dev/null || nocasematchWasOff=1
(( nocasematchWasOff )) && shopt -s nocasematch
# Loop over words in list and search for case-insensitive prefix match.
local w matches=()
for w in $words; do
if [[ "$w" == "$token"* ]]; then matches+=("$w"); fi
done
# Restore state of 'nocasematch' option, if necessary.
(( nocasematchWasOff )) && shopt -u nocasematch
COMPREPLY=("${matches[@]}")
}
关于bash - 在逐个命令的基础上为 bash 完成设置不区分大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10525659/