初めてPowerShellを勉強しました。忘れてしまいそうなので、基本的な構文をメモとして残します。
用語
用語 | 意味 |
---|---|
オブジェクト | ファイル1個(1行)が1オブジェクトです |
プロパティ | NameとかLengthの項目がプロパティです |
コマンドレット | PowerShellでの命令を言います |
元データ
下のフォルダを対象として、サンプルを記載します。カレントディレクトリを見たい時はコマンドレットGet-ChildItem
を使います。
> Get-ChildItem
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:00 20 test1.txt
-a---- 2021/05/01 12:01 10 test2.txt
-a---- 2021/05/01 12:02 30 test3.csv
オブジェクトの抽出
ファイル名(プロパティName
)にtxt
を含むオブジェクトだけ抽出します。
> Get-ChildItem | Where-Object Name -like '*txt*'
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:00 20 test1.txt
-a---- 2021/05/01 12:01 10 test2.txt
更新日時(プロパティLastWriteTime
)が2021/05/01 12:01
より大きいオブジェクトだけ抽出します。
> Get-ChildItem | Where-Object LastWriteTime -gt '2021/05/01 12:01'
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:02 30 test3.csv
最初の1行を抽出します。
> Get-ChildItem | Select-Object -First 1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:00 20 test1.txt
最後の1行を抽出します。
> Get-ChildItem | Select-Object -last 1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:02 30 test3.csv
ソート
プロパティLength
で並び替えます。
> Get-ChildItem | Sort-Object Length
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:01 10 test2.txt
-a---- 2021/05/01 12:00 20 test1.txt
-a---- 2021/05/01 12:02 30 test3.csv
プロパティLength
で逆順に並び替えます。
> Get-ChildItem | Sort-Object Length -Descending
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/05/01 12:02 30 test3.csv
-a---- 2021/05/01 12:00 20 test1.txt
-a---- 2021/05/01 12:01 10 test2.txt
プロパティの抽出と確認
Name
とLength
のプロパティのみ取り出します。出力の順番も決定します。
> Get-ChildItem | Select-Object Name,Length
Name Length
---- ------
test1.txt 20
test2.txt 10
test3.csv 30
プロパティの確認をします。表示されなかったプロパティも見ることができます。
> Get-ChildItem | Get-Member
Name MemberType Definition
---- ---------- ----------
・・・(省略)・・・
Extension Property string Extension {get;}
・・・(省略)・・・
Length Property long Length {get;}
Name Property string Name {get;}
・・・(省略)・・・
集計
オブジェクト数を数えます。
> Get-ChildItem | Measure-Object | Select-Object Count
Count
-----
3
プロパティLength
の合計を数えます。
> Get-ChildItem | Measure-Object Length -sum | Select-Object sum
Sum
---
60
拡張子(プロパティExtension
)毎に集計します。
> Get-ChildItem | Group-Object Extension
Count Name Group
----- ---- -----
2 .txt {test1.txt, test2.txt}
1 .csv {test3.csv}
変数
変数は$
から始まります。型宣言はありません。
> $a = 1
> $a + 1
2
変数に文字も入れることができます。計算が行われる時には、左側の型で計算が行われます。上の例では、[数値]+[数値]なので[数値]、下の例では、[文字]+[数値]なので[文字]になります。
> $b = `abc`
> $b + 1
abc1
配列も使えます。
> $c = @( 1,2,3 )
> $c = @(@(1,2),@(3,4))
> $c[0][1]
2
連想配列も使えます。;
を使い1行で書く方法と、1行づつ分けて書く方法があります。
> $c = @{'a'=1;'b'='abc'}
> $c = @{
'a'=1
'b'='abc'
}
> $c['b']
abc
また、変数にはオブジェクトも入れることができます。下の例では、Ge-ChildItem
で取得した3つのオブジェクト(配列)を変数$c
に入れています。
> $c = Get-ChildItem | Select-Object Name,Length
> $c
Name Length
---- ------
test1.txt 20
test2.txt 10
test3.csv 30
変数$c
の最初のオブジェクトを取り出します。
> $c[0]
Name Length
---- ------
test1.txt 20
変数$c
から特定のプロパティを取り出すこともできます。
> $c.Name
test1.txt
test2.txt
test3.csv
文字列と操作
文字は'
か"
で囲みます。
> 'Start'
Start
"
で囲まれた文字の中に変数がある場合は、その場所にその変数の値が入ります。
> "3 - 2 = $a"
3 - 2 = 1
'
で囲まれた文字はそのまま使われます。
> '3 - 2 = $a'
3 - 2 = $a
文字列の連結には+
を使います。
> $b+'def'
abcdef
文字列の長さを調べるにはLength
を使います。
> 'abcdef'.Length
6
文字を取り出すには、Substring
を使います。
> 'abcdef'.Substring(1,3)
bcd
検索で文字列の取り出すには下のような正規表現の判定を使った方法があります。この判定で見つかった文字列が$Matches
に勝手に入ります。なお、複数該当していても最初の1個しか入らないので注意してください。(下の例ではf456
も該当するが表示されていない)
> 'abc123def456' -match '\w\d+'
True
> $Matches
Name Value
---- -----
0 c123
ファイルの入出力
変数$b
をoutput.txt
として出力(上書き)します。ファイルの中身を見たい時はコマンドレットGet-Content
を使います。
> $b | Set-Content .\output.txt
> Get-Content .\output.txt
abc
ファイルoutput.txt
にEnd
を追記します。
> "End" | Add-Content .\output.txt
> Get-Content .\output.txt
abc
End
変数$c
をcsvファイルtest.csv
として出力します。
> $c | Export-Csv .\test.csv
> Get-Content .\test.csv
#TYPE Selected.System.IO.FileInfo
"Name","Length"
"test1.txt","20"
"test2.txt","10"
"test3.csv","30"
csvファイルtest.csv
を変数$d
に入れます。
> $d = Import-Csv .\test.csv
> $d
Name Length
---- ------
test1.txt 20
test2.txt 10
test3.csv 30
データ変換
変数$c
をJSON形式に変換します。
> $c | ConvertTo-Json | Set-Content .\test.json
> Get-Content .\test.json
[
{
"Name": "test1.txt",
"Length": 20
},
{
"Name": "test2.txt",
"Length": 10
},
{
"Name": "test3.csv",
"Length": 30
}
]
JSON形式を読み込みます。
> Get-Content .\test.json | ConvertFrom-Json
Name Length
---- ------
test1.txt 20
test2.txt 10
test3.csv 30
変数$c
をHTML形式に変換します。
> $c | ConvertTo-Html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/></colgroup>
<tr><th>Name</th><th>Length</th></tr>
<tr><td>test1.txt</td><td>20</td></tr>
<tr><td>test2.txt</td><td>10</td></tr>
<tr><td>test3.csv</td><td>30</td></tr>
</table>
</body></html>
条件分岐
コマンドレットif
を使います。
> if ($a -eq 1) { '等しい' } else { '等しくない' }
等しい
> if ($a -eq 2) { '2と等しい' } elseif ($a -eq 1) { '1と等しい' } else { '等しくない' }
1と等しい
コマンドレットswitch
もあります。
> switch ($a)
{
2 { '2と等しい' }
1 { '1と等しい' }
default { '等しくない' }
}
1と等しい
PowerShellの比較演算子を下に記載します。
意味 | PowerShellの記入例 | Pythonの記入例 |
---|---|---|
等しい | \$a -eq \$b | a == b |
等しくない | \$a -ne \$b | a != b |
大きい | \$a -gt \$b | a > b |
以上 | \$a -ge \$b | a >= b |
以下 | \$a -le \$b | a <= b |
小さい | \$a -lt \$b | a < b |
ワイルドカード | 'abc' -like '*b*' | モジュールglob を使用する |
ワイルドカードの否定 | 'abc' -notlike '*b*' | モジュールglob を使用する |
正規表現 | 'abc123' -match '^\w*\d*$' | モジュールre を使用する |
正規表現の否定 | 'abc123' -notmatch '^\w*\d*$' | モジュールre を使用する |
配列に含まれる | @(1,2,3) -contains 1 | 1 in [1,2,3] |
配列に含まれない | @(1,2,3) -notcontains 1 | 1 not in [1,2,3] |
ループ
コマンドレットForEach-Object
を使い、変数$c
のプロパティName
の値を1つづつ表示します。
ForEach-Object
がパイプから受け取ったオブジェクトは変数$_
に格納されます。その変数$_
のプロパティName
を取り出しています。
> $c | ForEach-Object { $_.Name }
test1.txt
test2.txt
test3.csv
おわりに
次回はPowerShellを使ったスクリプトを作ってみたいと思います。、