最近、昔作ったUnityプロジェクトを整理するためにPowerShellを使う機会があった。
実際に少し長めの処理を書いたり、複数のコマンドをつないだりしていると、
PS C:\Users\User>
>>
|
といった表示や記号を、「見たことはあるけど、ちゃんと説明できるほど理解していない」と気づいた。
今回は、実際の作業で使ったPowerShellの基本をおさらいとして整理する。
PS C:\Users\User> は何を示しているのか
PS C:\Users\User>
は、
PowerShellを使っていて、
現在 C:\Users\User にいます
という意味。
ここに表示されているパスを見ると、現在どのフォルダを基準に操作しているのかが分かる。
Set-Location で現在いるフォルダを移動する
Set-Location "$env:USERPROFILE\Desktop"
この1行は、現在いるフォルダをユーザーのDesktopへ変更している。
実行前が、
PS C:\Users\User>
なら、実行後は、
PS C:\Users\User\Desktop>
になる。
Set-Location はLinuxやGit Bashで使う cd に近い。
.\ は「現在のフォルダ」
PowerShellスクリプトを実行するときに、
.\sample.ps1
のように書く。
この1行は、現在いるフォルダにある sample.ps1 を実行している。
ここで、
.\
は「現在のフォルダ」を表す。
そのため、現在いるフォルダに sample.ps1 が存在しなければ、
コマンドとして認識されません
といったエラーになる。
実際に今回も、スクリプトを保存した場所とPowerShellの現在地が違ったため実行できないことがあった。
>> はエラーではなく「続きを待っている」
PowerShellを使っていると、
>>
が表示されることがある。
たとえば、
$roots = @(
と入力すると、
>>
になる。
この1行では ( を開いたままなので、PowerShellが「まだコマンドが続く」と判断している。
たとえば、
$roots = @(
"$env:USERPROFILE\Documents"
"$env:USERPROFILE\Desktop"
)
と最後まで入力すると実行される。
@(...) は、複数の値をまとめた配列を作る書き方。
この例では、DocumentsとDesktopの2つのパスを $roots に入れている。
パイプ | の途中でも >> になる
こんな入力でも、
$projects |
Sort-Object Updated -Descending |
PowerShellは続きを待つ。
最後の | は、「この結果を次の処理へ渡す」という意味なので、その次の処理がまだ書かれていないから。
そこで、
Format-Table Name, Updated
と続けると、
$projects |
Sort-Object Updated -Descending |
Format-Table Name, Updated
という1つの処理になる。
この処理は、
プロジェクト一覧
↓
更新日時の新しい順に並べる
↓
NameとUpdatedを表として表示する
という流れ。
| は左側の結果を右側へ渡す
PowerShellでよく出てきたのが、
|
という記号。
これは「パイプ」と呼ばれる。
たとえば、
$projects |
Sort-Object Updated -Descending |
Format-Table Name, Updated
を分けて見る。
$projects
プロジェクトの一覧を取り出す。
Sort-Object Updated -Descending
受け取った一覧を Updated の降順、つまり新しい順に並べる。
Format-Table Name, Updated
受け取った結果から Name と Updated を表として表示する。
つまり | で、
取得
↓
並べ替え
↓
表示
と処理をつないでいる。
$ から始まるものは変数
PowerShellでは、
$projects
$root
のように $ から始まる名前がよく出てくる。
これは変数。
たとえば、
$name = "Sample"
この1行は、$name という変数に "Sample" を入れている。
Write-Host $name
この1行は、$name の中身を画面に表示している。
結果は、
Sample
になる。
$_ は「今処理している1件」
今回特に分かりにくかったのが、
$_
だった。
たとえば、
$projects |
Where-Object {
$_.SizeMB -le 150
}
この処理は、$projects の中からサイズが150MB以下のプロジェクトだけを残している。
ここで、
$_
は「現在処理している1件」を表す。
そして、
$_.SizeMB
は「現在処理しているプロジェクトの SizeMB の値」という意味。
SizeMB はPowerShellにもともと用意されているものではなく、今回のスクリプトでプロジェクトの容量をMB単位で持つために付けたプロパティ名。
たとえば、
Name = SampleProject
SizeMB = 42.1
というデータなら、$_.SizeMB は 42.1 を指す。
さらに、
$_.SizeMB -le 150
は、
現在のプロジェクトの容量が150MB以下か
を判定している。
-le は less than or equal、つまり「以下」という意味。
そのため、
Where-Object {
$_.SizeMB -le 150
}
全体では、
SizeMBが150以下のものだけ残す
という処理になる。
foreach は一覧を1件ずつ処理する
今回のスクリプトでは、
foreach ($project in $projects) {
Write-Host $project.Name
}
のような処理も使った。
この1行は、$projects に入っているプロジェクトを1件ずつ $project に取り出して処理している。
$project.Name
は、現在取り出しているプロジェクトの Name プロパティを参照している。
処理のイメージは、
1件取り出す
↓
処理する
↓
次の1件を取り出す
↓
処理する
という繰り返し。
長い処理も1行ずつ読むと分かりやすい
今回使った処理の1つがこれ。
$projects |
Where-Object { $_.SizeMB -le 150 } |
Sort-Object Updated -Descending |
Select-Object -First 5
最初は長く見えるが、1つずつ見ると分かりやすい。
$projects
プロジェクト一覧を処理の開始地点にする。
Where-Object { $_.SizeMB -le 150 }
容量が150MB以下のプロジェクトだけ残す。
Sort-Object Updated -Descending
残ったプロジェクトを更新日時の新しい順に並べる。
Select-Object -First 5
その中から先頭5件だけ取り出す。
全体では、
プロジェクト一覧
↓
150MB以下に絞る
↓
新しい順に並べる
↓
先頭5件を取る
という処理になる。
PowerShellの長いコマンドも、パイプ | ごとに分けて読むとかなり理解しやすかった。
まとめ
今回おさらいした記号や表示をまとめると、
PS C:\...>
PowerShellの現在地
>>
まだ入力が続いている
$
変数
$_
現在処理している1件
|
左側の結果を右側の処理へ渡す
.\
現在のフォルダ
-le
以下
という意味になる。
特に今回、
$projects |
Where-Object { $_.SizeMB -le 150 } |
Sort-Object Updated -Descending
のような処理を実際に使ったことで、
「長いPowerShellコマンドを丸ごと覚える」のではなく、
どんなデータが流れているか
↓
今どんな条件で絞っているか
↓
次に何をしているか
と順番に読む方が理解しやすいと分かった。
次は、今回のUnityプロジェクト整理で使った、
Get-ChildItem
Test-Path
Join-Path
Group-Object
Measure-Object
などのファイル操作をまとめたい。