Bash-show建议

Bash-show建议,bash,Bash,使用Git,当我键入以下内容时: $ git statsu min_cost=65535 # "Infinity" for choice in status rebase commit; do wagner_fischer "$input" "$choice" if (( wf_cost < min_cost )); then min_cost=$wf_cost suggestion=$choice fi done echo "Y

使用Git,当我键入以下内容时:

$ git statsu
min_cost=65535  # "Infinity"
for choice in status rebase commit; do
    wagner_fischer "$input" "$choice"
    if (( wf_cost < min_cost )); then
        min_cost=$wf_cost
        suggestion=$choice
    fi
done
echo "You typed $input, did you mean $suggestion?"
我得到

git: 'statsu' is not a git command. See 'git --help'.

Did you mean this?
    status
我如何使用Bash复制它


当然,我可以通过对所有可能的转置字母制作一个巨大的
大小写来做到这一点。。。但那要花很长时间,而且看起来真的很脏

case $1 in
  "statsu")
    suggestion="status"
  ;;
  "satsus")
    suggestion="status"
  ;;
  ...
esac
我如何在自己的程序中复制这种行为?

(相关问题,但这是关于配置git本身以打印此消息的问题)

(我不知道git是否就是这样做的,但它会工作的)。有一个叫做的概念可以用来测量两个字符串之间的距离。在这种情况下,您将计算输入(
statsu
)和每个可能匹配项(
status
commit
rebase
)之间的编辑距离,然后建议产生最小编辑距离的一个

Wagner-Fischer算法可以很容易地递归实现,尽管效率很低,但是对于短字符串来说,它应该足够快,以便与您的用例进行比较

# Warning: not tested, but should be close
# return (cost) is in variable wf_cost
wagner_fischer () {
    local t0 t1 t2
    if [[ -z $1 ]]; then
        # Base case 1: first string is empty
        wf_cost=${#2}
    elif [[ -z $2 ]]; then
        # Base case 2: second string is empty
        wf_cost=${#1}
    elif [[ ${1:0:1} == ${2:0:1} ]]; then
        # Strings have identical first characters, recurse on the
        # rest of each string
        wagner_fischer "${1:1}" "${2:1}"
    else
        # Strings have differing first characters; recurse on
        # the rest of each string, but add 1 to the result to accommodate
        # the initial difference.
        #
        # Pick lowest cost of possible operations:
        wagner_fischer "${1:1}" "$2"     # deletion case
        t0=$wf_cost
        wagner_fischer "${1}" "${2:1}"   # insertion case
        t1=$wf_cost
        (( t0 < t1 )) && t1=$t0
        wagner_fischer "${1:1}" "${2:1}" # substitution case
        t2=$wf_cost
        (( t1 < t2 )) && t1=$t2
        (( wf_cost=t1 + 1))
    fi
}
#警告:未测试,但应关闭
#退货(成本)为可变wf_成本
瓦格纳·菲舍尔(){
局部t0 t1 t2
如果[[-z$1]];则
#基本情况1:第一个字符串为空
wf#U成本=${2}
elif[-z$2]];然后
#基本情况2:第二个字符串为空
wf#U成本=${1}
elif[${1:0:1}==${2:0:1}];然后
#字符串具有相同的第一个字符,在
#每个字符串的其余部分
瓦格纳·菲舍尔“${1:1}”${2:1}”
其他的
#字符串具有不同的第一个字符;在
#每个字符串的其余部分,但在结果中添加1以适应
#最初的差异。
#
#选择可能操作的最低成本:
wagner_fischer“${1:1}”“$2”#删除案例
t0=wf\U美元成本
wagner_fischer“${1}”${2:1}”插入格
t1=wf\U美元成本
((t0
要找到最接近的建议,您可以像这样使用上述函数:

$ git statsu
min_cost=65535  # "Infinity"
for choice in status rebase commit; do
    wagner_fischer "$input" "$choice"
    if (( wf_cost < min_cost )); then
        min_cost=$wf_cost
        suggestion=$choice
    fi
done
echo "You typed $input, did you mean $suggestion?"
min_cost=65535#“无限”
对于状态中的选择,请重新设置提交的基础;做
瓦格纳·菲舍尔“$input”$choice”
如果((wf_成本<最小成本));然后
最低成本=$wf\U成本
建议=$choice
fi
完成
echo“您键入了$input,是指$SUPPORATION吗?”

你想这样做是为了什么?顶级命令?任意程序的子命令?用bash编写的特定程序的子命令?还有什么吗?一般来说,做好这项工作需要一个字典距离算法,而这在native bash中并不容易实现。他想要编程一个脚本,这样,如果你在git中键入了错误的内容,它将按照我设计的程序的子命令进行编程。嗯<代码>我的程序tpoy
。“你的意思是
myprogram typo
?你可以用它来避免拼写错误。有趣的是-我想知道是否有任何算法是通过键盘上键之间的接近程度来加权的……当然;链接的wikipedia文章中显示的算法假定每次插入、删除和替换的权重。在上述实现中n、 我只是假设这三个字母都有相同的成本。我认为插入和删除的成本仍然相同,但替换成本将是两个字母之间的相对距离(分配这样的权重将是读者的练习)哦,嘿@chepner!你刚刚编辑了我的另一个bash问题
:)
这是这个问题最有可能的解决方案。@gniourf\u gniourf我刚刚重新阅读了你所做的编辑,注意你使用的是一个全局变量来累积距离,而不是像my(deleted)那样使用退出状态假设注释。是的,这是为了避免多个子shell(这些子shell通过这样的递归疯狂地生成)。我真的破坏了什么吗?我记得它似乎以这种方式工作得很好(我记得它是不可用的,因为子shell太慢)。如果我做错了什么,请随时恢复/修复!