这是关于 Bash 开发和编码使用 RegEx 的可移植 Bash 脚本。
在 Mac 上使用 Bash RegEx,我可以执行以下操作:
coconut-mac$ a='bananacoconutman'; [[ "$a" =~ banana(.*?)man ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut
很好。在很多地方都很有用。喜欢。
当我尝试这样做时,它失败了:
coconut-mac$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*?)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
这精确的运行相同的命令完美关于企鹅:
coconut-linux$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*?)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut
- 为什么?
- 如何修复它以使脚本可移植?
编辑:在 Mac 上:
OS X version: 10.8.2
Bash version: 4.2.37(2)-release
在 Ubuntu 12.04 LTS 上:
Linux kernel version: 3.2.0-29-generic-pae
Linux version: Ubuntu 12.04.1 LTS
Bash version: 4.2.24(1)-release
答案1
在我的 Mac 上,info bash / =~ RET
显示:
附加二元运算符
=~', is available, with the same precedence as
==' 和 `!='。使用时,运算符右侧的字符串被视为扩展正则表达式并进行相应匹配(如 regex3))。
man 3 regex
说:
重复运算符(
?',
*'、+', or bounds) cannot follow another repetition operator. A repetition operator cannot begin an expression or subexpression or follow
^' 或 '|')。
man 3 regex
我在 GNU regex或中没有看到任何类似的文档info regex
。
?
如果我从您的中删除(.*?)
并执行以下操作,它将在两个操作系统上运行:
$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut
答案2
这可能是答案:
Darwin(10.8.1/2)上的默认 bash:
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)
例如,Ubuntu 12 LTS 上的默认 bash:
GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
使其可移植将会远离较新的 bash 怪癖并使用诸如sed
、、awk
等等之类的东西。