Splunk: サブサーチの結果を1つの文字列にまとめてSPL文中で使用する、formatコマンドとreturnコマンド

使用する機会があったのでメモ。

###### 実施環境： Splunk Free 8.2.2

 Splunk のコマンドの1つに、 format コマンドというものがあります。
このコマンドは一般的には、サブサーチの結果を検索条件に含めるために使用されます。

```Splunk:Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log"
    [
      | makeresults count=1
      | eval log_level="ERROR"
      | fields log_level
      | format
    ]
| table _time, log_level, event_message
```

![スクリーンショット 2021-10-24 21.28.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/98575286-558f-9ead-aae1-e5b47879e4fa.png "format使用例")

ここで、上記の SPL 文についてもう少し考えてみます。
上記のような SPL 文は、文の先頭で暗黙的に search コマンドを使用しています。
つまり、 format コマンドを適用したサブサーチの結果は、 search コマンドの引数に与えられたと考えることができます。
とするとここで1つ思い浮かぶのが、「では他のコマンドでも format コマンドの結果を引数として適用できるのか?」ということです。
結論から言えば、できます。

```Splunk:Splunk
| makeresults count=10
| streamstats count AS Num1
| where
    [
      | makeresults count=10
      | streamstats count AS Num2
      | eval Num1 = Num2 * 2
      | fields Num1
      | format
    ]
| table Num1
```

![スクリーンショット 2021-10-24 21.16.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/f40a0275-a96d-1bf9-858a-2734d4a677cc.png "format-where")


それだけではなく、 format コマンドはもっとポテンシャルを持ったコマンドです。
試しに上記の SPL 文からサブサーチだけを抜き出すと、次のようになっています。

```Splunk:Splunk
| makeresults count=10
| streamstats count AS Num2
| eval Num1 = Num2 * 2
| fields Num1
| format
```

![スクリーンショット 2021-10-24 21.18.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/4c276725-8160-511a-d79c-4df65766c5ad.png "formatのみ")

 search というフィールドに、サブサーチから組み立てられた文字列が入っています。
先の SPL 文ではこの組み立てられた文字列が search コマンドや where コマンドの引数として適用されたわけです。
実はこの「組み立てられた文字列」というのがミソで、 format コマンドの引数を変えると他にも色々な組み立て方ができるのです。
ちょっと以下の SPL 文で試してみましょう。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Num1
| eval Num2 = Num1 * 10
| eval Num3 = Num1 * 100
| fields Num1, Num2, Num3
```

![スクリーンショット 2021-10-24 21.42.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/de85a7ea-f43b-41f7-43ae-65ad3ce666c4.png "format組み立て前")


引数なしで format コマンドを適用すると、以下のようになります。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Num1
| eval Num2 = Num1 * 10
| eval Num3 = Num1 * 100
| fields Num1, Num2, Num3
| format
```

![スクリーンショット 2021-10-24 21.51.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/a26c74d9-f783-0e7b-1a6f-86f65b77802a.png "format引数なし")


 format コマンドに、引数を与えてみます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Num1
| eval Num2 = Num1 * 10
| eval Num3 = Num1 * 100
| fields Num1, Num2, Num3
| format "行始まり" "列始まり" "列区切り" "列終わり" "行区切り" "行終わり"
```

![スクリーンショット 2021-10-24 21.51.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/4176ef15-d341-f1d7-2684-78ada80e9d96.png "format引数あり")

このように、 format コマンドの本質は、サブサーチの結果を1つの文字列に固めて、 SPL 文中で使用する点にあります。
これを応用すると、例えば結果に表示する列名をサブサーチで指定する、なんてこともできたりします。

```Splunk:Splunk
| makeresults count=3
| eval Test1=1, Test2=2, Test3=3, Test4=4, Test5=5
| table
    [
      | makeresults count=5
      | streamstats count AS Num1
      | eval Num2 = Num1 * 2
      | eval Col_Name = "Test" + Num2
      | fields Col_Name
      | format "" "" "" "" "" ""
      | eval search = replace(search, "Col_Name=", "")
    ]
```

![スクリーンショット 2021-10-24 21.57.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/74a82235-2e67-78ee-a11a-9894d619a22d.png "format応用")

 format コマンドと類似したコマンドに、 return コマンドというものもあります。
こちらも、サブサーチの結果を search というフィールドに固めることができます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Num1
| eval Num2 = Num1 * 10
| eval Num3 = Num1 * 100
| return 3 Num1, Num2, Num3
```

![スクリーンショット 2021-10-24 22.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/aac84908-9c8a-9e52-3500-0d9d5e8fd715.png "returnフィールドあり")

ただ、 return コマンドは上記のような使い方よりも、
フィールド名不要で値のみ欲しい場合によく使用されます。
フィールド名の前に$をつけることで、値のみを取得できます。

```Splunk:Splunk
| makeresults count=1
| eval Num2 = 1
| return $Num2
```

![スクリーンショット 2021-10-24 22.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/c7d2695c-4d28-a4aa-db0c-c09f4cb5a0d2.png "returnフィールドなし")

```Splunk:Splunk
| makeresults count=5
| eval Num1 =
    [
      | makeresults count=1
      | eval Num2 = 1
      | return $Num2
    ]
| table Num1
```

![スクリーンショット 2021-10-24 22.07.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/609e8bfb-409d-c1c3-c363-50df4618dfd0.png "return使用例")

なお、引数で明示しない限り、 return は先頭の行のみを
結果の組み立てに使用します。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Num1
| return $Num1
```

![スクリーンショット 2021-10-24 22.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/69827138-1645-fa9c-0537-3c4d6d4f6731.png "return複数行")