使用match来查找仅使用bash的字符串中的子字符串

时间:2012-03-07 08:03:03

标签: regex bash match

虽然我几乎可以肯定这已被覆盖,但我似乎无法找到任何具体的内容。当我继续学习bash的旅程时,我一直在找到我感到困惑的部分,为什么事情会像他们那样发生。

在编写脚本时,搜索和替换或仅匹配字符串中的子字符串很可能是您首先要做的事情之一。但是,尝试坚持使用单一语言或一组工具很难在bash中完成,因为您可以通过多种方式解决大多数问题。我正尽力用bash保持尽可能低的水平。我遇到了一个障碍,我需要有人向我解释。

在bash中使用匹配进行子字符串搜索会根据我使用的正则表达式给出不同的结果,我不知道为什么。

#!/bin/bash
Stext="Hallo World"
echo `expr "$Stext" : '^\(.[a-z]*\)'` # Hallo
echo `expr "$Stext" : '.*World'`      # 11

虽然两者都搜索一个单词,我认为,但两者都不会返回他们找到的内容。为什么?

4 个答案:

答案 0 :(得分:63)

您可以使用BASH_REMATCH中的bash变量来获取匹配的字符串:

$ Stext="Hallo World"
$ [[ $Stext =~ ^.[a-z]* ]] && echo $BASH_REMATCH
Hallo
$ [[ $Stext =~ ^(.[a-z]*) ]] && echo ${BASH_REMATCH[1]}
Hallo
  

正则表达式中带括号的子表达式匹配的子字符串保存在数组变量 BASH_REMATCH 中。索引为0的BASH_REMATCH元素是与整个正则表达式匹配的字符串部分。索引为n的BASH_REMATCH元素是与第n个带括号的子表达式匹配的字符串部分。

答案 1 :(得分:30)

两个表达式都是等价的,区别在于您使用的正则表达式:

$ echo `expr "$Stext" : '^\(.[a-z]*\)'`
Hallo
$ echo `expr "$Stext" : '^.[a-z]*'`
5
$ echo `expr "$Stext" : '\(.*World\)'`
Hallo World
$ echo `expr "$Stext" : '.*World'`
11

正如你所看到的,圆括号是返回匹配长度或匹配本身的不同之处。

您可以在Advanced Bash-Scripting Guide的Chapter 10中找到更多示例。

答案 2 :(得分:0)

我做了这个简单的功能:

match() {
    TRUE=1
    FALSE=0
    match_return=0
    echo $1 | grep $2 >/dev/null
    [ $? -eq 0 ] && match_return=$TRUE || match_return=$FALSE
}

用法:

match Testing Test ; [ $match_return -eq 1 ] && echo "match!" || echo "nope"
  

整个代码:https://gist.github.com/TeeBSD/5121b3711fad40a09455

答案 3 :(得分:-1)

快速搜索字符串...一个选项是grep。
如果找不到,则返回空,否则匹配:

found=`echo $big | grep -e $short`

if [ ! -z $found ]; then echo 'There is a match'; else echo 'No no'; fi