Why doesn't this simple RegEx work with sed?

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.

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/bash
ZIP="software-1.3-licensetypeone.zip"
VERSION=$(sed 's/software-//g;s/-(licensetypeone|licensetypetwo).zip//g' <<< $ZIP)

echo $VERSION

terminal

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

4 Answers

up vote 3 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

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.–  curtisblackwell Nov 12 '12 at 13:07
 
@curtisblackwell: Does yoursed support ; to separate commands? In some versions, multiple-e are needed: sed -e 's///' -e 's///'.–  choroba Nov 12 '12 at 13:14
 
yeah, it supports multiple commands separated by;. I'm using that elsewhere.–  curtisblackwell Nov 12 '12 at 13:16
 
@curtisblackwell: Does $ZIP contain whitespace? If it can, use<<< "$ZIP".–  choroba Nov 12 '12 at 13:18
 
no, it doesn't, but i should probably do use quotes in case it gets renamed.–  curtisblackwell Nov 12 '12 at 23:57
add comment

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

shopt -s extglob
ZIP="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.–  curtisblackwell Nov 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 jackman Nov 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?–  curtisblackwell Nov 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 jackman Nov 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.–  curtisblackwell Nov 13 '12 at 1:06
add comment
$ 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 tagged or ask your own question.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值