(正規表現)
のように正規表現を()
で括ると、マッチした値を参照できるようになる。捕捉グループ、capturing groupと呼ばれ、大体のプログラミング言語の正規表現ライブラリで対応している。
sedだと、\1
, \2
, ... という記法で後方参照できる。
Rubyだと、正規表現内では \1
, \2
, ... という記法で後方参照でき、マッチ処理が終わったあとであれば$1
, $2
, ... という特殊変数によって n 番目の括弧にマッチした文字列を参照できる。
Javaだと、String#replaceAll
で置換するなど $1
, $2
, ... という記法で後方参照でき、Matcher
でマッチ処理をする場合はマッチ処理が終わったあとにMatcher#group(int n)
で n 番目の括弧にマッチした文字列を参照できる。
Awkでは以下のようにマッチした値を参照する。
awk 'match($0, /request_time:([0-9\.]+)/, a){print a[1]}' access.log
match
の第一引数にマッチさせたい文字列を入れ、第二引数に/正規表現/
を入れる。第三引数に設定した変数にmatch
の結果が入る。正規表現の一部(または全部)を()
でくくっていた場合、第三引数の変数a
はa[0]
が元の文字列、a[n]
に n 番目の括弧にマッチした文字列が入る。
Awkで後方参照するには、sub
, gsub
ではなくgensub(/正規表現/, "置換文字", "g" or 1-, 対象文字列)
を使う。"g" or 1-
の部分は、"g"
を指定すると対象文字列のマッチする箇所全部を置換し、1
や2
を指定すると対象文字列のマッチする箇所の1番目、2番目を置換する。置換文字の中で後方参照が使え、\\1
のように指定する。
先ほどのマッチした値を参照したコードを書き換えると次のようになる。
awk '{print gensub(/request_time:([0-9\.]+)/, "\\1", "g")}' access.log
対象文字列は省略でき、省略した場合は$0
が指定されたことになる。