Why doesn't this simple RegEx work with sed?

来源:互联网 发布:seo的优化 编辑:程序博客网 时间:2024/05/01 09:29

current community

your communities

more stack exchange communities

Stack Exchange
Take the 2-minute tour×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Why doesn't this simple RegEx work with sed?

up vote0 down vote favorite

This is a really simple RegEx that isn't working, and I can't figure out why. According tothis, it should work.

I'm on a Mac (OS X 10.8.2).

script.sh

#!/bin/bashZIP="software-1.3-licensetypeone.zip"VERSION=$(sed 's/software-//g;s/-(licensetypeone|licensetypetwo).zip//g' <<< $ZIP)echo $VERSION

terminal

$ sh script.sh1.3-licensetypeone.zip
share|improve this question
 
 
add comment

4 Answers

activeoldest votes
up vote3 down vote accepted

Looking at the regex documentation for OS X 10.7.4 (but should apply to OP's 10.8.2), it is mentioned in the last paragraph that

Obsolete (basic) regular expressions differ in several respects. | is an ordinary character and there is no equivalent for its functionality...

... The parentheses for nested subexpressions are \(' and)'...

sed, without any options, uses basic regular expression (BRE).

To use | in OS X or BSD's sed, you need to enable extended regular expression (ERE) via-E option, i.e.

sed -E 's/software-//g;s/-(licensetypeone|licensetypetwo).zip//g'

p/s: \| in BRE is a GNU extension.


Alternative ways to extract version number

  1. chop-chop (parameter expansion)

    VERSION=${ZIP#software-}VERSION=${VERSION%-license*.zip}
  2. sed

    VERSION=$(sed 's/software-\(.*\)-license.*/\1/' <<< "$ZIP")

    You don't necessarily have to match strings word-by-word with shell patterns or regex.

share|improve this answer
 
 
add comment
up vote3 down vote

sed works with simple regular expressions. You have to backslash parentheses and a vertical bar to make it work.

sed 's/software-//g;s/-\(licensetypeone\|licensetypetwo\)\.zip//g'

Note that I backslashed the dot, too. Otherwise, it would have matched any character.

share|improve this answer
 
 
Copied and pasted your line in there, but it still didn't work for me.– curtisblackwellNov 12 '12 at 13:07
 
@curtisblackwell: Does yoursed support ; to separate commands? In some versions, multiple-e are needed: sed -e 's///' -e 's///'.– chorobaNov 12 '12 at 13:14
 
yeah, it supports multiple commands separated by;. I'm using that elsewhere.– curtisblackwellNov 12 '12 at 13:16
 
@curtisblackwell: Does $ZIP contain whitespace? If it can, use<<< "$ZIP".– chorobaNov 12 '12 at 13:18
 
no, it doesn't, but i should probably do use quotes in case it gets renamed.– curtisblackwellNov 12 '12 at 23:57
add comment
up vote3 down vote

You can do this in the shell, don't need sed, parameter expansion suffices:

shopt -s extglobZIP="software-1.3-licensetypeone.zip"tmp=${ZIP#software-}VERSION=${tmp%-licensetype@(one|two).zip}

With a recent version of bash (may not ship with OSX) you can use regular expressions

if [[ $ZIP =~ software-([0-9.]+)-licensetype(one|two).zip ]]; then    VERSION=${BASH_REMATCH[1]}fi

or, if you just want the 2nd word in a hyphen-separated string

VERSION=$(IFS=-; set -- $ZIP; echo $2)
share|improve this answer
 
 
Your last suggestion solves my problem. Thank you! However, I still don't understand why the RegEx doesn't work.– curtisblackwellNov 13 '12 at 0:00
 
choroba explained it in his answer. Different programs (perl, sed, bash, etc) implement regular expressions in different ways. With sed, you need to escape the parentheses to give them their special meaning.– glenn jackmanNov 13 '12 at 0:45
 
That sounds right, but even when I escaped them, it didn't work. Is it possible that my version of sed just doesn't support parentheses and/or pipes in regular expressions?– curtisblackwellNov 13 '12 at 1:00
 
highly unlikely. Did you also escape the pipe? Read choroba's answer very carefully. You will also want to checkman sed and (perhaps) man ed to learn about regexes implemented by sed.– glenn jackmanNov 13 '12 at 1:03
 
I read his answer carefully. Re-read many times, because I thought it was correct. However, even copying and pasting the RegEx didn't work. I'll check man sed again, and look into ed. Thanks.– curtisblackwellNov 13 '12 at 1:06
add comment
up vote0 down vote
$ man sed | grep "regexp-extended" -A2       -r, --regexp-extended              use extended regular expressions in the script.
share|improve this answer
 
 
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 taggedregex sed or ask your own question.

0 0