見つかった各パターンを繰り返し、ループ内の他のキャプチャグループにアクセスしたいと思います。可能であれば、grep
またはを使用してawk
3番目のパターンを学習しないように使い続けたいのですが、実際に必要な場合はもう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
式が無効であるかどうかです。
たとえば、入力行を配列に保存し、単語blah
とhello
固定パターンを保存するとします。
#!/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