Regex 如何根据Bash版本/特性编写条件代码?
我正在我的一个Bash脚本中使用Regex 如何根据Bash版本/特性编写条件代码?,regex,bash,msysgit,Regex,Bash,Msysgit,我正在我的一个Bash脚本中使用=~。但是,我需要使脚本与不支持该操作符的Bash版本兼容,特别是与它一起提供的Bash版本。我有一个变通办法,使用expr match,但由于某些原因,它在MacOSX上同样不起作用 因此,我只想在[-n“$MSYSTEM”-a${BASH_VERSINFO[0]}-lt 4]时使用expr匹配,否则使用=。问题是Bash似乎总是解析整个脚本,即使msysgitbash在运行时执行变通操作,它在解析脚本时仍然会遇到=~ 是否可以根据Bash版本在同一脚本中有条件
=~
。但是,我需要使脚本与不支持该操作符的Bash版本兼容,特别是与它一起提供的Bash版本。我有一个变通办法,使用expr match
,但由于某些原因,它在MacOSX上同样不起作用
因此,我只想在[-n“$MSYSTEM”-a${BASH_VERSINFO[0]}-lt 4]时使用expr匹配
,否则使用=
。问题是Bash似乎总是解析整个脚本,即使msysgitbash在运行时执行变通操作,它在解析脚本时仍然会遇到=~
是否可以根据Bash版本在同一脚本中有条件地执行代码,或者我是否应该寻找其他方法来解决此问题?我当前的解决方案是在所有平台上使用
grep-q
。这避免了任何条件或复杂的代码构造
可能仅在运行时使用
eval
解析包含=~
的代码也会起作用,但这会使代码的读取更加复杂。在您的情况下,可以使用等效的模式匹配替换正则表达式
[[ $foo = \[+([0-9])\][[:space:]]* ]]
一些解释:
- 模式与整个字符串匹配。以下正则表达式和模式是等效的:
和^foo$
foo
和^foo
foo*
和foo$
*foo
和foo
*foo*
匹配封闭模式的一个或多个实例,在本例中为+(…)
。也就是说,如果[0-9]
和$pattern
匹配相同的字符串,那么$regex
和+($pattern)
也匹配相同的字符串($regex)+
案例
语句。不过,它需要有相当数量的不同glob模式来列举所有的角落案例
case $foo in
[![]* | \[[!0-9]* | *[!][0-9[:space:]]* | *[!0-9[:space:]] | \
*\]*[![:space:]] | *[!0-9]\]* | \[*\[* | *\]*\]* )
return 1;; # false
\[*[0-9]*\]* )
return 0;; # true
*)
return 1;; # false
esac
可能是将“=~”相关代码分离到另一个文件。然后根据您的条件导入。比如[-n“$MSYSTEM”-a${BASH_VERSINFO[0]}-lt 4];然后来源“mycode.sh”。在这种情况下,bash将只在导入另一个脚本时解析代码。我也在考虑这一点,虽然它可能会起作用,但我更喜欢不需要创建额外文件的解决方案。或者可以在变量中定义代码并调用它?比如var='yourbash代码'。然后只使用$var。您能用模式匹配替换正则表达式吗?例如,使用
[[$foo=b*(a)]]
而不是[[$foo=~ba*]]
。不确定。。。我的正则表达式是^\[[0-9]+\][[:space:][]
。是否存在等效的模式匹配?尽管这需要启用扩展的全局模式(shopt-s extglob
)。但不在始终识别扩展模式的[…]
内extglob
允许您使用扩展模式生成路径名(例如,ls@([0-9]).txt
)(我本打算在手册页或发行说明中对此进行引用,但现在我似乎找不到它。我想至少可以追溯到3.2)嗯,我得到了-bash:conditional expression中的语法错误:意外的token`('
在GNU bash,3.2.48(1)版-发行版(x86_64-apple-darwin10.0)
是的。现在我不确定我记住了什么。我至少可以确认它在4.1中是不必要的。