PowerShellのSelect-Stringで前後行を含む文字列だけを取得する

## はじめに

PowerShellの`Select-String`では、`Context`パラメーターを使用すると、検索でヒットした行の「前後行を含めた結果」を取得することができます。
この前後行を含めて、該当行の「文字列のみ」を取得しようとしたところ、少し工夫が必要だったため、今回はその内容を記載します。

### 環境
- Windows PowerShell 5.1.22000.282

## 結論

```powershell
Select-String -Path [ファイル名] -Pattern [検索パターン] -Context [前の行数], [後の行数] | % { $_.Context.PreContext + $_.Line + $_.Context.PostContext }
```
コマンドの具体例は、[成功例](#成功例)で確認可能です。

## 検証

### やりたいこと

- `Select-String`でヒットした行の、前後行を含めた文字列のみを取得する

### 検証用データ

検証用に、以下のようなファイルを準備しました。

```sample.txt
◆あ行
・あ
・い
・う
・え
・お

◆か行
・か
・き
・く
・け
・こ

◆さ行
・さ
・し
・す
・せ
・そ
```

### 成功例

"◆"を含む行とその後ろ2行までを取得する場合のコマンドです。

```powershell
Select-String -Path sample.txt -Pattern "◆" -Context 0, 2 | % { $_.Context.PreContext + $_.Line + $_.Context.PostContext }
```

結果

```
◆あ行
・あ
・い
◆か行
・か
・き
◆さ行
・さ
・し
```

該当行とその後ろ2行を含んだ文字列だけを取得できています。

### 失敗例

#### 結果をそのまま取得

```powershell
Select-String -Path sample.txt -Pattern "◆" -Context 0, 2
```

結果

```

> sample.txt:1:◆あ行
  sample.txt:2:・あ
  sample.txt:3:・い
> sample.txt:8:◆か行
  sample.txt:9:・か
  sample.txt:10:・き
> sample.txt:15:◆さ行
  sample.txt:16:・さ
  sample.txt:17:・し


```

該当行を示す`>`やファイル名なども含まれてしまいます。

#### `Select-Object`で、`Line`と`Context`を選択して取得

```powershell
Select-String -Path sample.txt -Pattern "◆" -Context 0, 2 | Select-Object Line, Context
```

結果

```

Line Context                                       
---- -------                                       
◆あ行  Microsoft.PowerShell.Commands.MatchInfoContext
◆か行  Microsoft.PowerShell.Commands.MatchInfoContext
◆さ行  Microsoft.PowerShell.Commands.MatchInfoContext


```

該当行のみの情報が欲しい場合は、`Select-Object`で`Line`で絞り込めばよかったのですが、前後行(`Context`)については、この方法ではうまくいきません。

### 調査

`Context`プロパティを`Get-Member`してみたところ、`PreContext`プロパティに前の行、`PostContext`プロパティに後の行の結果が格納されているようでした。
以下は、`Context`プロパティを表示させた例です。

```powershell
PS D:\workspace> Select-String -Path sample.txt -Pattern "◆" -Context 0, 2 | % { $_.Context }

PreContext PostContext  DisplayPreContext DisplayPostContext
---------- -----------  ----------------- ------------------
{}         {・あ, ・い} {}                {・あ, ・い}
{}         {・か, ・き} {}                {・か, ・き}
{}         {・さ, ・し} {}                {・さ, ・し}
```

Microsoft Docsにも記載がありました。
>Properties（一部抜粋）<table>
><tr>
><td>PostContext</td>
>        <td>Lines found after a match.</td>
>    </tr>
>    <tr>
>        <td>PreContext</td>
>        <td>Lines found before a match.</td>
>    </tr>
></table>
> 引用元：MatchInfoContext Class (Microsoft.PowerShell.Commands) | Microsoft Docs 
>
> https://docs.microsoft.com/en-us/dotnet/api/microsoft.powershell.commands.matchinfocontext?view=powershellsdk-7.0.0

これを`Line`プロパティと結合させると、[結論](#結論)にあるコマンドとなり、意図した結果を取得できるようになりました。

## 参考

- Select-String (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/select-string?view=powershell-7.2
- MatchInfo Class (Microsoft.PowerShell.Commands) | Microsoft Docs https://docs.microsoft.com/en-us/dotnet/api/microsoft.powershell.commands.matchinfo?view=powershellsdk-7.0.0
- MatchInfoContext Class (Microsoft.PowerShell.Commands) | Microsoft Docs https://docs.microsoft.com/en-us/dotnet/api/microsoft.powershell.commands.matchinfocontext?view=powershellsdk-7.0.0