PowerShell入門について

# PowerShell ~~は~~ も 初心者~~未満~~[^1]ですが…

[^1]: 実務でもすこしスクリプトをくませてもらったりして 2020 年になった現在ではいちおう初心者をなのれる程度にはなりました。

ずばり[こちら][69885]の記事がおきにいりです。

* [使う気が無い人向けのPowerShell入門 - 南よ! 海の見える方! — LiveJournal][69885]

[69885]:https://karino2.livejournal.com/69885.html

もっともわたしは「想定読者」の条件にあてはまりませんが、とてもおもしろくよめました。

# しかし僭越ながらツッコミっぽいことを…
「[パイプ Oriented 環境、PowerShell](https://karino2.livejournal.com/70074.html "パイプ Oriented 環境、PowerShell - 南よ! 海の見える方! — LiveJournal")」についてです。

> ```awk
cat test.csv | awk -F, '{print $2}'
```

の PowerShell 代替が

> ```powershell
cat test.csv | %{ $_.Split(",")[1] }
```

とのことですが、じゃあ ` awk -F, '{print $2, $NF}' ` の代替は?とおもったときに答えをみつけるのにやや苦労しました[^2]――こうするのかなと:

```powershell
cat test.csv | % { $_.Split(',')[1, -1] -join ' ' }
```

[^2]: もっとも、これはこの記事自体の問題点ではありませんけど。

つぎに

> ```awk
cat test.csv | awk -F, 'BEGIN {total = 0} $4 ~ /20090405/ { total+=$3 }END {print "Total:" total}'
```

の同等が

> ```powershell
cat .\test.csv | ?{ $_.Split(",")[3] -match "20090405" } | %{$total=0}{ $total += $_.Split(",")[2]}{$total}
```

で、後者のほうが思考の流れにそってパイプラインの左から右へ処理をつなげていけてよいとのことです。でも、それなら AWK のほうでも

```awk
cat test.csv | awk -F, '$4 ~ /20090405/' | awk -F, 'BEGIN {total = 0} { total+=$3 }END {print "Total:" total}'
```

とかじゃだめなんですか、とおもってしまいます。

あと AWK でパターン・アクションを複数かいたとき、たとえば

```awk
cat test.csv | awk -F, '
    BEGIN { total1 = total2 = 0 }
    $4 ~ /20090405/ { total1 += $3 }
    $NF ~ /New-Opportunity/ { total2 += $3 }
    END { print "Total1:", total1, "Total2:", total2 }'
```

の PowerShell 同等には ` ? { ... } ` はつかえず結局

```powershell
cat test.csv | % { $total1 = $total2 = 0 } {
    if ($_.Split(',')[3] -match '20090405') { $total1 += $_.Split(',')[2] }
    if ($_.Split(',')[-1] -match 'New-Opportunity') { $total2 += $_.Split(',')[2] }
} { "Total1: $total1 Total2: $total2" }
```

みたいなことになってしまうんではないかと…。

そういうわけで、とてもおもしろいとおもいつつもじつはこの記事の主張が本当のところはわかってません。しかし、わかっていないのはわたしがまだ PowerShell をまったくわかっていないからで、この記事の趣旨が「あー、そういうことだったのか」とわかるようになることを期待しつつ学習をつづけていきたいとおもいます。

# Switch 文について (2020/1/4 加筆)

switch 文に AWK でパターン・アクションを複数かいたとき相当の機能があることをいまごろしりました。

```powershell
cat test.csv | % { $total1 = $total2 = 0 } {
    switch (,$_.split(',')) {
        { $_[3] -match '20090405' } { $total1 += $_[2] }
        { $_[-1] -match 'New-Opportunity' } { $total2 += $_[2] }
    }
} { "Total1: $total1 Total2: $total2" }
```

最初の `$_` はパイプをながれてきたブツですが、それ以外の `$_` は `switch` 文のもの、ここでは `$_.split(',')` (文字列の配列) です。switch は配列を要素ごとに `foreach` みたくします[^3]。そこで `,` [^4]をつけてもとの配列を要素とする要素数 1 の配列をつくってもとの配列がまるっと `$_` にわたされるようにしています。

[^3]: [About Switch](https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_Switch?view=powershell-5.1 "about_Switch - PowerShell | Microsoft Docs")

[^4]: [Comma operator](https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_Operators?view=powershell-5.1#comma-operator- "about_Operators - PowerShell | Microsoft Docs")

ちなみに以下の記事がすばらしいです。

- [Parsing Text with PowerShell (1/3)](https://devblogs.microsoft.com/powershell/parsing-text-with-powershell-1-3/ "Parsing Text with PowerShell (1/3) | PowerShell")
- [Parsing Text with PowerShell (2/3)](https://devblogs.microsoft.com/powershell/parsing-text-with-powershell-2-3/ "Parsing Text with PowerShell (2/3) | PowerShell")
- [Parsing Text with PowerShell (3/3)](https://devblogs.microsoft.com/powershell/parsing-text-with-powershell-3-3/ "Parsing Text with PowerShell (3/3) | PowerShell")[^5]

[^5]: 最初のサンプル プログラムをコピペして実行するとエラーになります。なんと 43 行目の `if` の条件式がわたしのような初心者がやらかしがちな…。でもこの記事はほんといいです。