bash:部分匹配一个完整的单词
发布时间:2020-12-15 21:06:16 所属栏目:安全 来源:网络整理
导读:我写了一个bash脚本,它将一个命令作为第一个位置参数,并使用case构造作为类似于以下内容的调度: do_command() { # responds to invocation `$0 command ...`}do_copy() { # respond to invocation: `$0 copy...`}do_imperative() { # respond to invocation
我写了一个bash脚本,它将一个命令作为第一个位置参数,并使用case构造作为类似于以下内容的调度:
do_command() { # responds to invocation `$0 command ...` } do_copy() { # respond to invocation: `$0 copy...` } do_imperative() { # respond to invocation: `$0 imperative ...` } cmd=$1 shift case $cmd in command) do_command $* ;; copy) do_copy $* ;; imperative) do_imperative $* ;; *) echo "Usage: $0 [ command | copy | imperative ]" >&2 ;; esac 此脚本根据$1决定调用哪个函数,然后将剩余的参数传递给该函数.我想在不同的部分匹配上添加能力调度,但我希望以优雅的方式进行(优雅定义为既易于阅读又不会像眼睛或分心那样冗长的方式). 明显的功能(但不是优雅)解决方案可能是这样的: case $cmd in command|comman|comma|comm|com) do_command $* ;; copy|cop) do_copy $* ;; imperative|imperativ|imperati|imperat|impera|imper|impe|imp|im|i) do_imperative $* ;; *) echo "Usage: $0 [ command | copy | imperative ]" >&2 ;; esac 正如您所看到的,显式枚举每个命令名称的所有不同排列都会变得非常混乱. 有一会儿,我觉得使用像这样的通配符可能没问题: case $cmd in com*) do_command $* ;; cop*) do_copy $* ;; i*) do_imperative $* ;; *) echo "Usage: $0 [ command | copy | imperative ]" >&2 ;; esac 这不是一个眼睛.但是,这可能会导致不良行为,例如当$1作为“comblah”或其他不应被识别为有效参数的其他内容时调用do_command. 我的问题是:正确调度这样一个命令的最优雅(如上所述)的方法是什么,用户可以提供任何截然不同的截断形式的命令? 解决方法
我提出了以下解决方案,它应该适用于任何解决方案
与bourne兼容的shell: disambiguate() { option="$1" shift found="" all="" comma="" for candidate in "$@"; do case "$candidate" in "$option"*) found="$candidate" all="$all$comma$candidate" comma="," esac done if [ -z "$found" ] ; then echo "Unknown option $option: should be one of $@" >&2 return 1; fi if [ "$all" = "$found" ] ; then echo "$found" else echo "Ambigious option $option: may be $all" >&2 return 1 fi } foo=$(disambiguate "$1" lorem ipsum dolor dollar) if [ -z "$foo" ] ; then exit 1; fi echo "$foo" 是的,消除歧义的源代码并不漂亮,但我希望你大部分时间都不必查看此代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |