Bash - 显示建议

标签 bash

使用 Git,当我输入如下内容时:

$ git statsu

我明白了...

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

Did you mean this?
    status

我如何使用 Bash 复制它?


当然,我可以通过制作一个包含所有可能转置字母的巨大 case 来做到这一点……但这会花很长时间,而且看起来真的很脏……

case $1 in
  "statsu")
    suggestion="status"
  ;;
  "satsus")
    suggestion="status"
  ;;
  ...
esac

如何在我自己的程序中复制这种行为?

(相关问题 here,但这是在讨论配置 git ITSELF 以打印此消息)

最佳答案

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

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
}

要找到最接近的建议,您可以像这样使用上面的函数:

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?"

关于Bash - 显示建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26663620/

相关文章:

bash - 与 ps 的计数差异 | wc

linux - PulseAudio:获取源(麦克风)的当前音量

linux - bash 中的 dir 路径谜题?

macos - 固定宽度的 bash 提示符

bash 脚本,删除上一行?

git - 将存储库从 Github 迁移到自托管 Gitlab 时更新和修复 LFS

linux - 仅在尚未运行时运行 cron 作业

bash - 通过 bash 执行 sqlite 命令

Bash语法错误

bash - 为什么回显$?返回与预期不同的值?