在shell脚本中,提取中括号'[]'之间的字符串:
#!/bin/sh
STRING="hello,[sunny]! "
#extract substring 'sunny'
echo $STRING
SUBSTR=`expr "$STRING" : '.*\[\(.*\)\]'`
echo $SUBSTR
SUBSTR=$(expr "$STRING" : '.*\[\(.*\)\]')
echo $SUBSTR
SUBSTR=`echo "$STRING" | sed -n 's/.*\[\(.*\)\].*/\1/p'`
echo $SUBSTR
1)使用expr
SUBSTR=`expr "$STRING" : '.*\[\(.*\)\]'`
SUBSTR=$(expr "$STRING" : '.*\[\(.*\)\]')
解释:expr会提取小括号'()'中匹配到的字符串。注意,小括号和中括号字符都要转义。这两行脚本的效果是一样的。
2)使用sed(巧妙运用sed的替换功能)
SUBSTR=`echo "$STRING" | sed -n 's/.*\[\(.*\)\].*/\1/p'`
解释:
脚本最后的\p,是输出sed处理后的行;
\, 转义,理解正则表达式时,可以暂时将\剔除;
-n,限定/p只输出匹配成功的行;
/1,代表小括号'()'中匹配到的字符串;
s//,替换。关键的地方就在这里。
1) s/.*\[\(.*\)\].*/\1 的意思就是先通过正则表达式.*\[\(.*\)\].*对字符串$STRING进行匹配;
2) 如果匹配成功,会将\(.*\)匹配到的内容存储到/1变量;
3) 使用/1变量中的内容,替换正则表达式.*\[\(.*\)\].*匹配到的字符串。
可以看出正则表达式.*\[\(.*\)\].*匹配的是含有[]整个字符串,而(.*)提取[]之间的字符串并存储到了/1中,然后使用/1的内容替换整个匹配到的字符串,所以最后,实际输出的就是\1中字符串了。也就是\(.*\)中匹配到的内容。