awk または grep を使用したグループのキャプチャ

awk または grep を使用したグループのキャプチャ

見つかった各パターンを繰り返し、ループ内の他のキャプチャグループにアクセスしたいと思います。可能であれば、grepまたはを使用してawk3番目のパターンを学習しないように使い続けたいのですが、実際に必要な場合はもう1つ調べてください!)

次のようにしてください。

awk-or-grep -E '(blah(.*)hello=(.*))' sampletext | while read -r l; do 
    echo $0             #1st capture group
    echo $1             #2nd catpure group
    dosomethingwith $2  #3rd capture group
done

存在する?


テキスト例:

blah12687hello=123
nothingthatmatches
blah3211hello=123456
blah15butnottheotherpattern

前述のループを使用すると、次のように出力されます。

blah12687hello=123
12687
<it should run the command dosomethingwith 123>
blah3211hello=123456
3211
<it should run the command dosomethingwith 123456>

ベストアンサー1

シェルbash自体は、便宜上、必要に応じてキャプチャされたグループに対して正規表現マッチングを実行する方法を提供します。

=~二重括弧内の演算子は、[[演算子の左側に一致する文字列を持ち、右側のオペランドとして正規表現を使用して式をテストします。

if [[ "$str" =~ $re ]]; then

式が文字列と一致する場合は、文字列の一致部分が配列に格納され、キャプチャされた個々のグループをBASH_REMATCH繰り返すことができます。終了状態は、0正規表現が一致するか、1一致しないか、2式が無効であるかどうかです。


たとえば、入力行を配列に保存し、単語blahhello固定パターンを保存するとします。

#!/usr/bin/env bash

exampleStr=('blah12687hello=123' 'nothingthatmatches' 'blah3211hello=123456' 'blah15butnottheotherpattern')

re='blah([[:digit:]]+)hello=([[:digit:]]+)'

for str in "${exampleStr[@]}"; do
    if [[ "$str" =~ $re ]]; then
       for group in "${BASH_REMATCH[@]}"; do
           printf "%s\n" "$group"
       done
    else
       printf "No match \n"
    fi
done

上記のコードに示すように、正規表現をtrueに一致させると、配列を繰り返してキャプチャされたBASH_REMATCH各グループを印刷できます。フルスクリプト出力は次のとおりです。

blah12687hello=123     # Value of BASH_REMATCH[0]
12687                  # Value of BASH_REMATCH[1]
123                    # Value of BASH_REMATCH[2]
Regex not matches.
blah3211hello=123456
3211
123456
Regex not matches.

ご覧のとおり、正規BASH_REMATCH[0]表現が正常に一致する文字列部分は常に含まれており、キャプチャされた個々のグループにはindexから始まりアクセスできます1。キャプチャされた各グループを処理するカスタムロジックを作成できます。これはもともと意図したものとまったく同じです。


ファイル入力の読み取りに興味がある場合は、処理whileしたいファイルに入力リダイレクトを含むループを使用してください。

while IFS= read -r line; do
    if [[ "$line" =~ $re ]]; then
       for group in "${BASH_REMATCH[@]}"; do
           printf "%s\n" "$group"
       done
    else
       printf "No match \n"
    fi
done < inputFile.txt

おすすめ記事