Splunk: ワイルドカード・正規表現での検索におけるヒット条件毎の統計
必要な機会があったのでメモ。
実施環境: Splunk Free 8.2.2
前置き
文字列の検索において、条件毎のヒット数を算出することを考えます。
文字列が固定であれば、以下のように stats コマンドを使用することで容易に実現できます。
| makeresults count=10
| streamstats count AS CNT
| eval NUM = CNT % 3
| eval STR = "A" + NUM
| where STR = "A1" OR STR = "A2"
| stats count BY STR
では、この条件がワイルドカードや正規表現を含むものであればどうでしょうか。
やりたいこと
以下のようなデータを考えます。
STR |
---|
one |
two |
three |
four |
five |
| inputlookup "test_data.csv"
検索条件は「 t で始まる文字列」「 e で終わる文字列」の2つを指定します。
STR |
---|
t* |
*e |
| inputlookup "test_search.csv"
上記のデータにおいて「 t で始まる文字列」は2つ、「 e で終わる文字列」は3つあります。
この数字を導出することを目指します。
単純に検索すると
まずは単純に format コマンドで検索条件を組み立てて search コマンドで検索してみます。
where コマンドを使用しないのは where コマンドだとワイルドカードをそのまま利用できないためです。
| inputlookup "test_data.csv"
| search
[
| inputlookup "test_search.csv"
| format
]
STR |
---|
one |
two |
three |
five |
上記の結果をいろいろこねくり回してみましたが、この方針で目的を達成するのは難しそうです。
何が悪いのかを考えると、「どの条件でヒットしたのかが結果から判断できない」ということに気づきます。
以下のように条件毎にサーチ文を作って合成するという方法も思いつきますが、汎用性が無さすぎます。
| inputlookup "test_data.csv"
| search
[
| inputlookup "test_search.csv"
| head 1
| format
]
| eval STR_SEARCH = "t*"
| stats count BY STR_SEARCH
| append
[
| inputlookup "test_data.csv"
| search
[
| inputlookup "test_search.csv"
| tail 1
| format
]
| eval STR_SEARCH = "*e"
| stats count BY STR_SEARCH
]
STR_SEARCH | count |
---|---|
t* | 2 |
*e | 3 |
解決方法
いろいろ考えた結果、以下の方法に行き着きました。
| inputlookup "test_data.csv"
| join max=0
[
| inputlookup "test_search.csv"
| eval STR_SEARCH = STR
| eval STR_SEARCH_R = replace(STR,"\*","%")
| fields STR_SEARCH, STR_SEARCH_R
]
| where like(STR, STR_SEARCH_R)
| stats count BY STR_SEARCH
STR_SEARCH | count |
---|---|
*e | 3 |
t* | 2 |
ポイントは以下の2点です。
-
join コマンドの max オプションを使用して検索対象と検索条件の組を全て書き出す
-
where コマンドの like 関数を使用して、組毎に検索を実施する
ポイントの1点目ですが、 join コマンドの max オプションに 0 を指定すると全ての組み合わせを網羅する形での結合(交差結合)が実現できます。
これを利用して、検索対象と検索条件の組み合わせを、1組1行で全て書き出します。
| inputlookup "test_data.csv"
| join max=0
[
| inputlookup "test_search.csv"
| eval STR_SEARCH = STR
| fields STR_SEARCH
]
STR | STR_SEARCH |
---|---|
one | t* |
one | *e |
two | t* |
two | *e |
three | t* |
three | *e |
four | t* |
four | *e |
five | t* |
five | *e |
書き出した組み合わせについて、ポイントの2点目で行毎に検索を実施し、ヒットした行のみを抽出します。
2つのフィールドを比較するので、先ほどは逆に where コマンドである必要があります。
注意点として、 like 関数のワイルドカードは「任意の文字列」を表す文字が「*」でなく「%」になるので、そのように条件の文字列を変換しないとうまく動きません。
| inputlookup "test_data.csv"
| join max=0
[
| inputlookup "test_search.csv"
| eval STR_SEARCH = STR
| eval STR_SEARCH_R = replace(STR,"\*","%")
| fields STR_SEARCH, STR_SEARCH_R
]
| where like(STR, STR_SEARCH_R)
STR | STR_SEARCH | STR_SEARCH_R |
---|---|---|
one | *e | %e |
two | t* | t% |
three | t* | t% |
three | *e | %e |
five | *e | %e |
このようにすれば、「ヒットした値」と「ヒットした条件」の組が残るので、 stats コマンドで集計することができます。
正規表現
さらにこの方法だと、 like 関数を match 関数に変えるだけで正規表現にも対応することができます。
search コマンドで正規表現は使えないので、この方法は統計処理をしない検索だけでも有用かと思います。
| makeresults count=200
| streamstats count AS STR
| join max=0
[
| makeresults count=2
| streamstats count AS STR
| eval STR_SEARCH = "^" + STR + "*5{1,2}$"
| fields STR_SEARCH
]
| where match(STR, STR_SEARCH)
| stats count BY STR_SEARCH
Author And Source
この問題について(Splunk: ワイルドカード・正規表現での検索におけるヒット条件毎の統計), 我々は、より多くの情報をここで見つけました https://qiita.com/frozencatpisces/items/df11b84ee5e20b3979bc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .