2012-03-07 31 views
36

これはほぼ確実ですが、これに特有のものは何も見つかりません。私がbashを学ぶための旅を続けていくうちに、どうして物事が起こるのかについて私が困惑している部分を見つけ出します。bashだけで文字列内の部分文字列を見つけるためのマッチの使用

文字列内のサブ文字列を検索したり置換したりするだけで、スクリプトを作成するときに最初に行うことの1つが最も可能性が高いです。しかし、ほとんどの問題を複数の方法で解決できるように、単一の言語やツールセットに固執しようとすると、bashで行うのは難しいです。できるだけ低レベルでbashを使い続けるために最善を尽くしています。私は誰かが私に説明するのが必要なつまずきに遭遇しました。

サブストリングを使用すると、bashでの検索で一致する正規表現が異なる場合は、その理由がわかりません。単語の両方の検索が、

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

私は考えて、両方のは、彼らが見つけるものを返しません。どうして?

答えて

23

両方の式は等価で、違いは、使用する正規表現です:あなたが見ることができるように、

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

括弧の一致の長さや試合自体を返すためにどちらかの違いを作るものです。

さらに詳しい例は、高度なバッシュスクリプティングガイドのChapter 10です。

+0

感謝。 Bash-Scriptingのガイドは消化するのが簡単ではありません。 –

+1

この質問は[tag:bash]に関するもので、* forkへの/ usr/binの代わりに* builtin * regexを[@kev suggest](http://stackoverflow.com/a/9602260/1765658)/expr' *! –

49

あなたはマッチした文字列を取得するために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番目の括弧で囲まれた部分式に一致する文字列の部分です。

+0

...と '[[" Hello world "=〜^ [^ \] *]] && echo $ {#BASH_REMATCH}' - '5' ... –

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

+0

この投稿は質問や回答にはあまり関係ありません。 –

0

を... 1つのオプションはありますgrep。
見つからない場合は、それが一致している他、空を返します:私はあなたが提供するドキュメントを使用していましたが、何とかこれは機能を括弧取得できませんでした:) @jcollado簡単な説明のための

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

if [ ! -z $found ]; then echo 'There is a match'; else echo 'No no'; fi 
関連する問題