Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

This is about Bash development and coding of portable Bash scripts that use RegEx.

Using Bash RegEx, on a Mac, I can do this:

coconut-mac$ a='bananacoconutman'; [[ "$a" =~ banana(.*?)man ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut

Nice. Useful in many places. Like.

When I try doing this, it fails:

coconut-mac$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*?)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}

The exact same command runs perfectly on the penguin:

coconut-linux$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*?)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut
  • Why?
  • How to fix it to make the script portable?

EDIT: On the Mac:

OS X version: 10.8.2
Bash version: 4.2.37(2)-release

on 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
share|improve this question

migrated from stackoverflow.com Oct 3 '12 at 13:59

This question came from our site for professional and enthusiast programmers.

    
What versions of grep are you using on each system? There is no single version of Linux - what flavor/version are you using? –  Matt Ball Oct 3 '12 at 2:22
    
s/grep/bash/ >.> –  Ignacio Vazquez-Abrams Oct 3 '12 at 2:26
add comment

2 Answers

up vote 2 down vote accepted

On my Mac, info bash / =~ RET says:

An additional binary operator, =~', is available, with the same precedence as==' and `!='. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex3)).

man 3 regex says:

A repetition operator (?',*', +', or bounds) cannot follow another repetition operator. A repetition operator cannot begin an expression or subexpression or follow^' or `|'.

I don't see any analogous documentation in GNU regex's man 3 regex or info regex.

If I remove the ? from your (.*?) and do the following, it works on both OSes:

$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut
share|improve this answer
    
Nice write-up!! –  Robottinosino Oct 3 '12 at 2:45
add comment

This would probably be the answer:

Default bash on Darwin (10.8.1/2):

GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)

Default bash on, say, Ubuntu 12 LTS:

GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)

Making it portable would be stepping away from newer bash quirks and using things like sed, awk, whatnot.

share|improve this answer
    
Thanks! That's it... –  Robottinosino Oct 3 '12 at 3:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.