我使用了下面这段代码
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/ksh
zsh
=~
test
[
zsh
yash
在这里,您不需要正则表达式,通配符模式也可以工作:
[[ $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"]))}'