2026-03-29

PowerShell 7は魔法なのに、なぜ8年経っても偽物の5.1が座っているのか…

7年、8年ほど前に始まった PowerShell Ver.6 の頃の希望は、とっくの昔に消えてしまったな…いつまでもWindows標準はゴミの Windows PowerShell 5.1 のまま。
そして世の中の人は、ゴミの方しか認知していない。
いや、PowerShell自体ほとんど認知されてない。されてても「Windowsの管理ツール」くらいにしか思われてない…

PowerShell 7は結構すごいのに…
.NETを直接使えるから、何も追加で入れなくても何でも作れる、魔法みたいなスクリプト言語なんだ。
クラス書けるし、型もガッツリ使える。
かなり優秀なスクリプト環境だと思ってる。
ただし、インストールが必要という一点で全てが台無しになる…クソだな、これ。Windowsに最初から入ってるのが5.1のままってのが、全部の元凶…
「みんなに勧めたいけど、インストールさせてからじゃないと話が始まらない」って状況が、歯がゆい。

2019-03-05

文字列の扱いではまるポイント

Powershellが期待通りに動かずハマるポイント…
変数の型宣言が無くて楽だけど、いざというときにハマるポイントです。
Powershellに限らず、変数の型宣言が無い言語はみんな同じだと思う。
先ずは…文字、文字列、文字列配列の違いが分かってることが前提です。

# 文字列配列で間違いやすいポイント

# どれが文字列配列か
# ★実際に実行してみてね
## 変数
$String1 = 'これは文字列です。'         # 1つの文字列
$String2 = ('これも文字列です。')       # ()は先に処理するだけ。ここだと無いのと同じ。
$String3 = @('これは文字列配列です')    # @()は配列お宣言。中身が文字列なので、文字列配列
$String4 = @()                      # @()は配列お宣言。配列で初期化
$String4 += 'これも文字列配列です'      # 文字列を配列に追加
$String5 = 'じゃあ…これは?','これは文字列配列です。' # 2つの文字列なので、文字列配列になる。
## 配列長
$String1.Length
$String2.Length
$String3.Length
$String4.Length
$String5.Length
## 1つ目の配列の中身…
$String1[0]     # 文字列(文字配列)なので、1文字目を表示
$String2[0]     # 文字列(文字配列)なので、1文字目を表示
$String3[0]     # 文字列配列なので、1行目を表示
$String4[0]     # 文字列配列なので、1行目を表示
$String5[0]     # 文字列配列なので、1行目を表示

## 演算子の結果だと…
$String1 -match '文字'
$String5 -match '文字'
$String1 -match '?'
$String5 -match '?'
$String1 -match 'これ'
$String5 -match 'これ'
$String1 -ne 'a'
$String5 -ne 'a'

### ↑この結果の違いが理解できないと、バグを埋め込むことになります。
### 文字列として扱いたいのか、文字列配列として扱いたいのかを意識して扱うこと。

@($String1) -match '文字'   # 文字列配列化
$String5[0] -match '文字'   # 文字列配列の1つ目の文字列
$String5[1] -match '文字'   # 文字列配列の2つ目の文字列

2019-03-02

文字列配列の抽出

Powershellでの文字列抽出の例
正規表現(match)が多機能で一番汎用性があります。
抽出条件がシンプルなのであれば、処理が軽いワイルドカード(like)が使えます。
ただ、数十万回とか回さないと差は分からないと思う…。
同じスクリプト内で、正規表現とワイルドカードを織り交ぜるとバグを埋め込みやすいので、基本は正規表現に統一した方が良いです。

# 文字列配列
$Array = @()
$Array += '1行目:a'
$Array += '2行目:bb'
$Array += '3行目:ccc'
## 要素数(行数)
$Array.Length
$Array
## 正規表現で抽出①
$Array -match 'b'
## 正規表現で抽出②(上①と同じ結果)
foreach ( $String in $Array ) {
    if ( $String -match 'b' ) {
        $String
    }
}
## ワイルドカードで抽出①
$Array -like '*c'
## ワイルドカードで抽出②(上①と同じ結果)
foreach ( $i in 0..($Array.Length -1) ) {
    if ( $Array[$i] -like '*c' ) {
        $Array[$i]
    }
}

# 要注意
## 演算子 -match や -like は左側が変数か配列化で結果が異なります。この違いを理解していないとハマります。(上の抽出①と②に関連)
$Example1 = '単なる文字列'
$Example2 = @( '1行だけの文字列配列' )
$Example1 -match '文字列'
$Example2 -match '文字列'