Powershell備忘録（基本）

# 初めに
久々にPowerShellを触るときに、「この表現なんだっけ？」とならないための備忘録。
PowerShellと他言語の違いを中心に書く。

## 目次
- PowerShellの特徴
- 主な予約語
- If, else, elseif
- for, while
- リスト（配列）
- 関数
- 文字列出力
- 文字列操作
- キーボード入力
- グローバル変数
- その他

## Powershellの特徴
- 変数は"$"を付けて宣言
- オブジェクト指向/データをパイプラインで引き渡し
- 大文字・小文字の区別はしない

# 主な予約語
|キーワード|Pythonでの記法|備考|
|:---|:---|:---|
|true,false|`$true`,`$false`|先頭に”＄”をつける
|<,>,<=,>=|-lt,-gt,-le,-ge|"-"+"Less"/"Greater"+"Than"/"Equal"
|==,!=|-eq,-ne|"EQual","Not Equal"
|and,or,not|-and,-or,-not/!|notは"-not"か"!"
|elseif|elseif|そのまま|
|++|++|そのまま
# Hello World
`Write-Host`，`echo`でできる．`Write-Host`推奨？
文字列を出力後自動で改行する．`-NoNewline`を付けると改行しない．
```powershell
Write-Host "hello World"
echo "hello world"
Write-Host -NoNewline "hello World"
#hello world
#hello world
#hello world（改行なし）
```
# If,else,elseif
基本の書き方。
```powershell
if ($i -eq 0){
    Write-host "0"
}elseif($i -gt 0){
    Write-host "gt 0 "
}else{
    Write-Host "else"
}
```
{}は省略できない。
```powershell
#下の書き方はエラー。
if ($true)
    Write-Host "true"
```

# for, while
1から10まで繰り返す場合
```powershell
for($i=0;$i -lt 10;$i++){
    Write-Host $i
}
```
リスト（後述）を使う場合
```powershell
$list = "a","b","c","d","e","f"
foreach($s in $list){
    Write-Host $s
}
```

while文。 do while文もある。
```powershell
$n=0
while($n -lt 10){
    Write-Host $n
    $n++
}
```
# リスト
## 基本
一次元のリスト。配列のように扱える。
```powershell
$list1 = @("a","b","c","d")
#空のリスト
$list2 = @()
#@がなくても定義できる
$list3 = "a","b","c","d"
```
## 多次元リスト
```powershell
#多次元配列
$array=@(("1","a"),("2","b"),("3","c"))

Write-Host $array
foreach($line in $array){
    Write-Host $line
}
#追加する時に「,」を忘れない
$array +=,@("4","d")
Write-Host $array
```

# 関数
## 基本
function + 関数名で宣言。
呼び出し方は、`関数名`もしくは`関数名()`
```powershell
function func1($data){
    Write-Host $data
}
func1("hello world")
func1 "hello world"

```
引数の無い場合、呼び出すときに`()`は付けない。
```powershell
function func2(){
    Write-Host "hello"
}
#func2()      #×
func2         #〇
```
## 引数
関数に引数を付ける時は注意。
変数を引数にする場合、１つの変数ごとに`()`を付け、スペースで区切る。
複数の引数を持てるのは、`関数名 (変数１) (変数２)...`の書き方。
他の記述は、変数が結合されて関数に渡される。 
```powershell
function func3($a,$b){
    Write-Host $a
    Write-Host $b
}
$n1="str1"
$n2="str2"
func3 ($n1) ($n2)       #〇
func3(($n1),($n2))      #△
func3($n1,$n2)          #△
#func3(($n1) ($n2))    #×。エラー。

#str1
#str2
#str1 str2
#
#str1 str2
#
```

# 文字列出力
基本操作
`Write-Host`の後ろの一行が出力される．
```powershell
$str = "hello"
$num = 10
Write-Host $str "world"
Write-Host $str"world"
Write-Host $str + "world"
#hello world
#helloworld
#hello + world
```
出力するときは数値＋文字列でもOK。
```powershell
#数値＋文字列もOK
Write-Host $num+" is ten"
Write-Host $num" is ten"
Write-Host "ten is "$num
Write-Host "ten is "+$num
#10+ is ten
#10 is ten
#ten is  10
#ten is  +10
```
# 文字列操作
## 基本
文字列＋文字列
```powershell
$msg = $str+ "world"
Write-Host $msg
$msg = "$str world"
Write-Host $msg
#helloworld
#hello world
```
数値＋文字列
文字列を先に置くと，数値計算と解釈され，エラーが発生する．
```powershell
$msg = "$num is ten"
Write-Host $msg
$msg = 'ten is '+$num
Write-Host $msg
#エラー。数値計算と解釈される
$msg = $num+' is ten'
Write-Host $msg
#10 is ten
#ten is 10
#  60 |  $msg = $num+' is ten'
#     |  ~~~~~~~~~~~~~~~~~~~~~
#     | Cannot convert value "is ten" to type "System.Int32". Error: "Input string was not in a correct format."
```
## 数値⇔文字列変換
```powershell
$int1=10
$int2=20
$str1="10"
$str2="20"
$result_num=[int]$str1+[int]$str2
Write-Host $result_num
$result_str=[string]$int1+[string]$int2
Write-Host $result_str
#30
#1020
```
https://win.just4fun.biz/?PowerShell/%E6%95%B0%E5%80%A4%E3%82%92%E6%96%87%E5%AD%97%E5%88%97%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B
## 文字列の繰り返し
```powershell
$str="hoge"
$msg=$str*10
Write-Host $msg
#hogehogehogehogehogehogehogehogehogehoge
```
https://buralog.jp/powershell-string-repeat/
## 文字列の切り出し・切り取り
`$str.SubString(s,n)`メソッドで，文字列`$str`の`s`文字目から`n`の文字を切り取る．
`$str.IndexOf(x)`メソッドで，文字`x`の位置を特定することで，任意の文字列を切り出すことができる．
```Powershell
#cからgの間にある文字列を切り取り
$str="abcdefghi"
$start=$str.IndexOf("c")
$end=$str.IndexOf("g")
$msg=$str.Substring($start,$end-$start)
Write-Host $msg
# cdef
```
https://bayashita.com/p/entry/show/223

https://bayashita.com/p/entry/show/136

正規表現を利用する手もある．
## 文字列数
`.Length`プロパティで確認．
```powershell
$str="abcdefghi"
Write-Host $str.Length
# 9
```

# グローバル変数
関数の内外で同じ変数を使いたい場合，`global`を付けて使用する．外・内どちらにも必要．
```powershell
$global:g_val=1
$l_val=1
function add_val($n){
    $global:g_val+=$n*2
    $l_val+=$n*2
}
add_val(3)
Write-Host $g_val
Write-Host $l_val
#7
#1
```
# キーボード入力
```powershell
$input = Read-Host "press keyboard & Enter"
Write-Host $input
#キーボード入力＋Enter後，入力した1行が$inputに入る．
```