【PowerShell】while
で処理するより、パターンを|(パイプ)
にまとめた方が見やすくなる話
こんにちは。サーバエンジニア1年目です。
日々、PowerShellで業務効率化を試しているのですが、
今回は「ループ処理じゃなくても複数の条件をまとめて処理できる」という発見があったので、備忘録としてまとめてみました。
これまでは「複数の条件でデータを抜き出すにはループしかない」と思っていましたが
もっとシンプルに書けるやり方を紹介します
やりたいこと
1か月分の日々のログがあって、2/1, 2/2, 2/3のみを抽出したい
2/1,aaa
2/2,bbb
2/3,ccc
2/4,ddd
2/5,eee
↓抽出後
2/1,aaa
2/2,bbb
2/3,ccc
よくある書き方:while
で1行ずつ処理するパターン
$dates = @("2/1", "2/2", "2/3")
$lines = Get-Content "C:\logs\access.log"
$index = 0
while ($index -lt $lines.Count) {
$line = $lines[$index]
foreach ($date in $dates) {
if ($line -like "*$date*") {
Write-Output $line
break
}
}
$index++
}
このように、対象の日付を配列にまとめて1行ずつ確認する書き方は、これまでよく使っていました。
ですが、ループが重なっていて、あとから見返したときにちょっと分かりづらくなることもありました。
スッキリした書き方:パターンを変数にまとめて一気に処理
$pattern = '2/1|2/2|2/3'
Get-Content "C:\logs\access.log" | Select-String -Pattern $pattern
この方法を知って、「えっ、こんなに簡単にできるの?」と感動しました。
処理の意図がひと目でわかりやすいですし、日付を追加・削除するときも $pattern を書き換えるだけでOKです。
なぜこの書き方が良いのか?
コードが短く、読みやすい
条件の追加・削除が簡単
ロジックが直線的でわかりやすい
Select-String を使うことで、さらに後続処理にもつなげやすい(ここ重要)
おまけ:抽出したあとに処理を追加することも可能です
$pattern = '2/1|2/2|2/3'
Get-Content "C:\logs\access.log" |
Select-String -Pattern $pattern |
ForEach-Object {
$_.Line.ToUpper()
}
たとえば上の例では、抽出したログをすべて大文字に変換しています。
このように、パイプ(|)を使えば、次の処理へ簡単につなげることができます。
まとめ
これまで私は「一つの処理の中で複数の条件を使いたいときは、ループで一つずつチェックするしかない」と思い込んでいました。
ですが、今回のようにパターンを1つにまとめて Select-String を使えば、処理をもっと簡単に書けることがわかって、とても勉強になりました。
初心者なりに、こうした小さな工夫を積み重ねて、今後ももっと読みやすく、わかりやすいコードを書いていけるようになりたいと思います。