2026年3月11日水曜日

powershellで表形式の表示

最近動けばいいやと、powershellでスクリプトで処理させていると結構楽しくなってきます。 

使うほどに気になるのは、細かいところで、エラー処理とか出力内容とか。 

ファイルのタイムスタンプ操作で設定前と設定後の値を表示させていたのですが、表示方法をもう少し何とかならないかと。

どうせならpowershell風なテーブル表形式でもと思ったら、結構厄介。

オブジェクトのメンバ変数なら配列に入っていればそれなりになるはずだけど…そうでない場合は?という事で連想配列の配列で対応してみる。

助長ではあるもののこんな感じかな?

$vals = @()
$vals += [ValsClass]::new("new", $CreateTime, $LastWriteTime)
$vals += (@{Name="old"; CreateTime=(Get-ItemProperty $To).CreationTime; LastWriteTime=(Get-ItemProperty $To).LastWriteTime})
$vals += (@{Name="from"; CreateTime=$CreateTime; LastWriteTime=$LastWriteTime})

この配列を表示させるとこんな感じに。

Name                           Value
----                           -----
LastWriteTime                  26/03/10 21:58:57
CreateTime                     26/03/05 17:21:03
Name                           old
LastWriteTime                  26/03/05 17:21:08
CreateTime                     26/03/05 17:21:03
Name                           from 

これをSelect-Object * | Format-Table すると

LastWriteTime     CreateTime        Name
------------- ---------- ----
26/03/10 21:58:57 26/03/05 17:21:03 old
26/03/05 17:21:08 26/03/05 17:21:03 from 

[orderd]にしないと連想配列内の順序が保たれなくなるから、ですが、実装の処理上、末尾が最初にくる感じになってるみたいですね。

なので、連想配列の順序を保つために[orderd]@{}形式で配列に格納して表示させると

Name                           Value
---- -----
Name old
CreateTime 26/03/05 17:21:03
LastWriteTime 26/03/10 22:11:10
Name from
CreateTime 26/03/05 17:21:03
LastWriteTime 26/03/05 17:21:08

良い感じがしますが、これをSelect-Object * | Format-Tableさせてみると

Count IsReadOnly Keys                              Values                                       IsFixedSize SyncRoot
----- ---------- ---- ------ ----------- --------
3 False {Name, CreateTime, LastWriteTime} {old, 26/03/05 17:21:03, 26/03/10 22:11:10} False {[Name, ol…
3 False {Name, CreateTime, LastWriteTime} {from, 26/03/05 17:21:03, 26/03/05 17:21:08} False {[Name, fr…

となってしまいまいました。Select-Object *の状態をみてみると

Count          : 3
IsReadOnly : False
Keys : {Name, CreateTime, LastWriteTime}
Values : {old, 26/03/05 17:21:03, 26/03/10 22:11:10}
IsFixedSize : False
SyncRoot : {[Name, old], [CreateTime, 26/03/05 17:21:03], [LastWriteTime, 26/03/10 22:11:10]}
IsSynchronized : False


Count : 3
IsReadOnly : False
Keys : {Name, CreateTime, LastWriteTime}
Values : {from, 26/03/05 17:21:03, 26/03/05 17:21:08}
IsFixedSize : False
SyncRoot : {[Name, from], [CreateTime, 26/03/05 17:21:03], [LastWriteTime, 26/03/05 17:21:08]}
IsSynchronized : False

といった感じのオブジェクトになっています。これをいい感じにSelectなんとかしてFormatなんとかする方法が無さそうだったので、別の切り口を試してみました。

さらに助長になりそうですが、クラスを定義してオブジェクトの配列にしてみます。

class ValsClass{
$Name
$CreationTime
$LastWriteTime
ValsClass($Name, $CreationTime, $LastWriteTime){
$this.Name = $Name
$this.CreationTime = $CreationTime
$this.LastWriteTime = $LastWriteTime
}
}

$vals = @()
$vals += [ValsClass]::new("old", (Get-ItemProperty $To).CreationTime, (Get-ItemProperty $To).LastWriteTime)
:
$vals += [ValsClass]::new("new", (Get-ItemProperty $To).CreationTime, (Get-ItemProperty $To).LastWriteTime)

これを表示させてみると

Name CreationTime      LastWriteTime
---- ------------      -------------
old  26/03/05 17:21:03 26/03/11 00:16:58
new  26/03/05 17:21:03 26/03/05 17:21:08

となってSelectなんとかとかFormatなんとかせず、目的の形で出力できました。

PSObjectとしてやったらもっとスマートな感じになりそうですが、とりあえずこれでいいか。 

0 件のコメント:

コメントを投稿