为什么 =~ 运算符在 Solaris 上与正则表达式进行比较时会出现语法错误

为什么 =~ 运算符在 Solaris 上与正则表达式进行比较时会出现语法错误

我使用了下面这段代码

appcount_range="^[1-$APP_COUNT]$"
    until [[ $APP_OPTION =~ $appcount_range ]]
    do
            echo "INVALID CHOICE! Please enter a valid option:"
            read APP_OPTION
    done

它检查菜单选项是否输入正确。由于 APP_COUNT 是动态决定的,我无法对有效选项进行硬编码。这段代码在使用 ksh93 的基于 Linux 的服务器上完美运行,但相同的代码在使用 ksh88 的 Solaris 服务器上给出语法错误:

syntax error at line ## : '=~' unexpected

为什么 ksh88 中没有=~公认的操作符?我应该使用什么作为比较正则表达式的替代方法?

答案1

/bin/ksh这是 ksh88( Solaris 10 及更早版本的 和)会输出的错误/usr/xpg4/bin/sh

虽然[[ ... ]]语法确实来自 ksh,但=~内部是极少数实际的 bashism 之一。bash实际上是引入它的 shell(在 3.0 版本中)。

它后来被添加到(因此可以与Solaris 11 及更高版本的andksh93一起使用)和,但有一些变体(运算符也可以在and的/构建中使用)。 ksh88 自 90 年代以来就没有更新过(除了错误修复或某些系统上的 POSIX 一致性修复)。/bin/sh/bin/kshzsh=~test[zshyash

在这里,您不需要正则表达式,通配符模式也可以工作:

[[ $APP_OPTION = [1-$APP_COUNT] ]]

对于=运算符(来自 ksh),右侧操作数是通配符模式。或者您可以使用标准方法进行模式匹配:

case $APP_OPTION in
  [1-$APP_COUNT]) ...
esac

请注意,它不适用于任何大于 9. 的值[1-12],与[21-1]仅在 2 和 1 上匹配相同(可能还有与某些语言环境中相同的其他字符进行排序1))。

ksh 通配符模式在功能上等同于扩展正则表达式({x,y}ERE 现代变体中的间隔运算符除外),但语法不同:

  • .->?
  • .*->*
  • x*->*(x)
  • x|y->@(x|y)
  • x?->?(x)
  • x+->+(x)
  • [^x]->[!x]
  • x{3,5}-> xxx?(x)?(x)(ksh93 有{3,5}(x),ksh88 没有)。

如果您仍然需要使用正则表达式,则需要使用单独的实用程序:

expr "x$string" : "x$regexp" # BRE, anchored at the start

STRING=$string RE=$regexp command -p awk '
  BEGIN{exit(!(ENVIRON["STRING"] ~ ENVIRON["RE"]))}'

相关内容