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

Pra*_*kar 1 linux solaris ksh shell-script regular-expression

我使用了以下这段代码

appcount_range="^[1-$APP_COUNT]$"
    until [[ $APP_OPTION =~ $appcount_range ]]
    do
            echo "INVALID CHOICE! Please enter a valid option:"
            read APP_OPTION
    done
Run Code Online (Sandbox Code Playgroud)

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

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

为什么=~在 ksh88 中不是公认的操作员,我应该使用什么作为比较正则表达式的替代方法?

Sté*_*las 6

这是 ksh88(/bin/kshSolaris 10 及更早版本和/usr/xpg4/bin/sh)将输出的错误。

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

它被后来添加的ksh93(所以会与工作/bin/sh/bin/kshSolaris 11中的更新版本)和zsh与变化(一个=~运营商也可在test/[的builinzshyash)。ksh88 自 90 年代以来一直没有更新(除了错误修复或某些系统上的 POSIX 一致性修复)。

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

[[ $APP_OPTION = [1-$APP_COUNT] ]]
Run Code Online (Sandbox Code Playgroud)

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

case $APP_OPTION in
  [1-$APP_COUNT]) ...
esac
Run Code Online (Sandbox Code Playgroud)

请注意,它不适用于大于 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"]))}'
Run Code Online (Sandbox Code Playgroud)