web-dev-qa-db-ja.com

matchを使用して、bashのみを含む文字列内の部分文字列を検索する

これはほぼ確実にカバーされていますが、これに固有の何かを見つけることはできないようです。私はbashの学習の旅を続けながら、物事がそのように起こる理由について私が困惑している部分を見つけ続けています。

文字列内の部分文字列の検索と置換、または単に一致させることは、スクリプトを記述するときに最初に行うことの1つです。しかし、ほとんどの問題を複数の方法で解決できるため、bashで1つの言語またはツールセットに固執することは困難です。私は、bashで可能な限り低レベルに留まるように最善を尽くしています。私は、私に説明する誰かが必要であるというひっかかりに遭遇しました。

一致するbashで部分文字列検索を実行すると、使用する正規表現に応じて異なる結果が得られますが、その理由はわかりません。

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

どちらもWordを検索しますI thinkですが、どちらも検索結果を返しません。どうして?

40
Willem P. Botha

両方の式は同等であり、違いは使用する正規表現です。

$ 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 1 にあります。

30
jcollado

bashBASH_REMATCH変数を使用して、一致した文字列を取得できます。

$ 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番目の括弧で囲まれた部分式に一致する文字列の部分です。

67
kev

この単純な関数を作成しました:

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

0
Antonio Feitosa