PowerShellには力
があり、配列、連想配列、オブジェクト等を扱えます。パイプライン処理もできます。これを生かして手元で何かごちゃごちゃすると便利なのですが、普段使わないので忘れがちです。それを書き留めます。そして忘れます。
基礎
パイプライン処理ではforeach, where, select, sort
などのコマンドをよく使う。
渡されたデータの各要素に$_
でアクセスできる。
%
はforeach
を、?
はwhere
を意味するエイリアス。ややこしいので気をつけて使う。
@(1..10) | where {$_ % 2 -eq 0} | foreach {"${_} "} | Write-Host -NoNewline
# 2 4 6 8 10
(1-10の連番を生成し、2で割り切れる数のみ、空白で区切って、改行せずに出力)
ファイル名の変更
ls | foreach {ren $_ ($_.BaseName + ".txt")}
ls | ?{$_.Extension -eq ".log"} | %{ren $_ ($_.BaseName + ".txt")}
ls
はカレントディレクトリのファイルを列挙する。各ファイルオブジェクトには.BaseName
のようなメンバがある。
また、ren
はファイルオブジェクトと新ファイル名を受け取ってリネームする。
文字列を扱う
cat sparse.txt | where {$_ -ne ""} > dense.txt
# sparse.txt の空行を消したものを dense.txt として出力
$n = 10
echo ("$n + 1 = " + ($n+1))
# 10 + 1 = 11
echo( $n + 1 )
# 11
echo("" + ($n + 1))
# 11
echo("" + $n + 1 )
# 101
echo("${n}yen")
# 10yen
echo('${n}yen')
# ${n}yen
日付時刻
(Get-Date).GetType().Fullname
# System.DataTime という型
(Get-Date).AddHours(-1)
# 1時間前のDataTimeが得られる
ls | where {(Get-Date).AddHours(-1) -le $_.CreationTime}
ls | where {$_.CreationTime -le (Get-Date).AddHours(-1)} | rm
()
でコマンドを囲むと結果をオブジェクトとして扱える
連番で何かする
@(n..m)
で配列を作ってパイプで渡す。(n..m)
とも書ける。
@(1..10000) | foreach {"${_},user_${_}"} > foo.csv
- 生成されるデータ
- 1,user_1
- 2,user_2 ...
@(1..10000) | foreach{"$_" + ',"user ' + $_ + ' is here"'} > foo.csv
- 生成されるデータ
- 1,"user 1 is here"
- 2,"user 2 is here" ...
-
""
で括らないと変数が展開されないので先頭は"$_"
- 文字としてのダブルクォーテーションは
''
の中に書いた方が分かりやすい - 真ん中にある
$_
は""
で括る必要はない- (前方の文字列と
+
しているので文字列と解釈される)
- (前方の文字列と
補足
文法をおさらい
- 変数の先頭に
$
が付く -
|
でパイプ(次のコマンドに向けて出力)して、>
とか>>
でファイルに出力 -
$_
でパイプで送られてきたデータの各要素を参照 -
"
で囲むと$n
や${n}
という表記で、文字列中で変数を参照できる -
'
で囲むと変数を展開しない -
{}
で囲まれた処理を「スクリプトブロック」と言う -
()
でコマンドを囲むと結果をオブジェクトとして扱える -
[]
で配列やオブジェクトの各要素にアクセスする-
(ls)[0]
でカレントディレクトリのファイル1つを対象に取れる
-
cmdletの補足
-
ls
はGet-ChildItemのエイリアスで、例文の場合FileInfo
を返す-
BaseName
というプロパティに関するドキュメントが見つからない -
stackoverflow曰く、これはScriptPropertyなので色々処理があって結局
Name
を取ってくるらしい - (プロパティ値について)
-
ls testfile1.txt | Get-Member BaseName | format-list
TypeName : System.IO.FileInfo
Name : BaseName
MemberType : ScriptProperty
Definition : System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Remove($this.Name.Length -
$this.Extension.Length)}else{$this.Name};}
-
ren
はRename-Itemのエイリアス -
Get-Dateの返す
DateTime
についてオブジェクトのプロパティとメソッドを表示するには、パイプラインの下に オブジェクトを 送信します Get-Member。 たとえば、「 Get-Date | Get-Member 」のように入力します。
だそうです- いやドキュメントに書いといてくれよ
これマジ?
"a" + 1
👈 😉「a1」
1 + "a"
👈 🤬「値”a”を型"System.Int32"に変換できません。」
( "" + 1 + "a"
👈 😌「1a」)
@(1..10)
👈 😉「1, 2, ... 10」
@(1...10)
👈 😤「1, 0」(.10
が0.1
と解釈されて、丸めて0
)
@(1...50)
👈 🤔「1, 0」
@(1...51)
👈 🤔「1」
@(1...50000000000000005)
👈 🤯「1, 0」
@(1...50000000000000006)
👈 😇「1」(環境に依存しそう)
ビル・ゲイツ!!!