2011-08-23 110 views
2

我试图匹配格式为4.6或2.8的字符串的版本号。我有,我将在一个函数最终使用在我的.bashrc文件,找到OS版本如下:Bash脚本正则表达式

function test() { 
    string="abc ABC12 123 3.4 def"; 
    echo `expr match "$string" '[0-9][.][0-9]'` 
} 

然而,这种不匹配字符串中的3.4。任何人都可以在这里指出我正确的方向吗?

谢谢。

+0

看不出为什么它不工作 - 也许,尝试使用“。”因为它是逃避而不是在例如。 '[0-9] \。[0-9]' – pastacool

+0

是不是'[。]'任何单个字符?你的功能是否匹配任何东西?我不知道bash中正则表达式的具体情况,但我会认为匹配会像“2 1”一样。 – Oliver

+0

@oliver:如果在脚架内,则不会如此使用 – pastacool

回答

10

首先,你可以删除echo - expr打印其结果是在任何情况下到标准输出。

其次,你的正则表达式需要括号(否则它会打印匹配的字符数,而不是匹配本身),它需要以.*开头。

expr match "$string" '.*\([0-9][.][0-9]\)' 

info expr页:

STRING:正则表达式”

Perform pattern matching. The arguments are converted to strings 
and the second is considered to be a (basic, a la GNU `grep') 
regular expression, with a `^' implicitly prepended. The first 
argument is then matched against this regular expression. 

If the match succeeds and REGEX uses `\(' and `\)', the `:' 
expression returns the part of STRING that matched the 
subexpression; otherwise, it returns the number of characters 
matched. 
1
expr match "$string" '.*[0-9][.][0-9]' 
+1

不知道bash部分,但只是正则表达式将匹配所有内容,直到(包括)3.4 – pastacool

2

逆向思考:如果你正在寻找一个脚本确定操作系统版本,只需使用uname -runame -v(它的POSIX)。因为每个操作系统可能有不同的表达版本的方式,因此使用正则表达式可能会遇到问题。操作系统供应商在创造向前和向后的版本跳跃方面非常有创意,有些在这里有字母,甚至罗马数字也不是闻所未闻的(想想系统V)。

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/uname.html

我在.profile文件使用一个片段是这样的:

case "`uname -sr`" in 
    (*BSD*)  OS=`uname -s`;; 
    (SunOS\ 4*) OS=SunOS;; 
    (SunOS\ 5*) OS=Solaris;; 
    (IRIX\ 5*) OS=IRIX;; 
    (HP*)  OS=HP-UX;; 
    (Linux*) OS=Linux;; 
    (CYGWIN*) OS=Cygwin;; 
    (*)   OS=generic 
esac 
2

在Mac OS X 10.6.8:

# cf. http://tldp.org/LDP/abs/html/refcards.html#AEN22429 
string="abc ABC12 123 3.4 def" 
expr "$string" : '.*\([0-9].[0-9]\)' # 3.4 
6

根据您的版本bash,没有必要呼叫到expr:

$ [[ "abc ABC12 123 3.4 def" =~ [0-9][.][0-9] ]] && echo ${BASH_REMATCH[0]} 
3.4