如何匹配 case 语句中的特定单词或其部分?

如何匹配 case 语句中的特定单词或其部分?

假设有以下情况:

#!/bin/sh

case $1 in

e|ex|exa|exam|examp|exampl|example) echo "OK"
;;
t|te|tes|test) echo "Also OK"
;;
*) echo "Error!"
;;

esac

对于这种情况,是否有更优雅且同时符合 POSIX 标准的解决方案(即没有 bash、zsh 等)?

PS 不需要exampleeeeExam工作。

答案1

你可以做的是扭转比较:

case "example" in
  "$1"*) echo OK ;;
  *) echo Error ;;
esac

通过多个单词,您可以坚持自己最初的想法

case "$1" in
  e|ex|exa|exam|examp|exampl|example) : ;;
  t|te|tes|test) : ;;
  f|fo|foo) : ;;
  *) echo error ;;
esac

或使用循环和“布尔”变量

match=""

for word in example test foo; do
  case "$word" in
    "$1"*) match=$word; break ;;
  esac
done

if [ -n "$match" ]; then
  echo "$1 matches $match"
else
  echo Error
fi

您可以决定哪个更好。我觉得第一个很优雅。

答案2

你提到了“选项”在评论中,这让我觉得你可能正在尝试解析命令行选项。由于 POSIXgetopts实用程序无法解析“长选项”,例如--testor --example,我们可以要求 GNUgetopt为我们解析它们。

以下是一个 shell 脚本,它采用短选项-e-t,以及相应的“长选项”--example--test。长选项可以在命令行上指定为完整选项字符串的任何前缀字符串,例如--e等都--ex将解析为--example。在下面的代码中,--test/-t选项采用强制参数,由:相应的长选项字符串和短选项字符串后面的尾随表示。

GNU getopt( 的一部分util-linux)用于解析命令行。

#!/bin/sh

opts=$( getopt -o et: -l example,test: -- "$@" )
if [ "$?" -ne 0 ]; then
    echo 'Error in getopt' >&2
    exit 1
fi

eval set -- "$opts"
unset opts

unset testarg
while true; do
    case "$1" in
        -e|--example)
            echo 'Example option'
            shift
            ;;
        -t|--test)
            echo 'Test option'
            testarg=$2
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo 'Command line parsing error' >&2
            exit 1
    esac
done

if [ -n "$testarg" ]; then
        printf 'Test argument = "%s"\n' "$testarg"
fi

测试:

$ ./script -e
Example option
$ ./script --exa
Example option
$ ./script --exa -t hello
Example option
Test option
Test argument = "hello"
$ ./script --exa --te='hello world'
Example option
Test option
Test argument = "hello world"
$ ./script -et 'hello world'
Example option
Test option
Test argument = "hello world"
$ ./script -eethello
Example option
Example option
Test option
Test argument = "hello"

相关内容