見つかった各パターンをループして、ループ内のさまざまなキャプチャグループにアクセスしたいのですが、おそらくgrep
を使用します。 またはawk
(3番目の学習を避けるために、可能であればそれらに固執したいのですが、本当に必要な場合は、別の学習を行います!)
次のようなことをします:
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>
承認された回答:
bash
シェル自体は、必要に応じて、キャプチャされたグループを正規表現マッチング処理する方法を提供します。
=~
二重括弧内の演算子テスト式、[[
演算子の左側に一致文字列があり、右側のオペランドに正規表現があります。
if [[ "$str" =~ $re ]]; then
式が文字列と一致する場合、文字列の一致した部分がBASH_REMATCH
に格納されます。 個々のキャプチャされたグループにアクセスするためにループオーバーできる配列。終了ステータスはです。 正規表現が一致する場合、
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]
正規表現によって正常に一致した文字列の部分が常に含まれ、キャプチャされた個々のグループにはインデックス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