2010年11月27日土曜日

◆集計プロパティ(Select-Object)

以前PowerShell: ◆オブジェクトにプロパティを追加する(Add-Member)でも使用した集計プロパティ。

余り説明せずに使っていたので今一度その使い方を確認してみる。
集計プロパティはSelect-Objectだけで使えるものではないが、いちばん基本的なコマンドレットであるSelect-Objectを例に説明する。

PS>dir d:\desktop\test1


    ディレクトリ: D:\desktop\test1


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2010/11/25     15:28          0 test1.txt
-a---        2010/11/25     15:28          0 test2.txt


PS>dir d:\desktop\test1 | select mode,name

Mode                                                        Name
----                                                        ----
-a---                                                       test1.txt
-a---                                                       test2.txt

こんな感じでプロパティを射影するのが基本的な使い方。SQLと同じイメージ。

ここで出力フォーマットを弄ってみる。


PS>dir d:\desktop\test1 | select mode,{$_.name + "です"}

Mode                                                        $_.name + "です"
----                                                        ----------------
-a---                                                       test1.txtです
-a---                                                       test2.txtです


本来プロパティ名を指定するところに式を指定するのでスクリプトブロックで指定する。
スクリプトブロックの中ではパイプラインオブジェクトが$_変数で参照できる。
ただし、これではタイトルがいただけない。
この様な時のためにタイトルを指定する機能を提供するのが集計プロパティと呼ばれるものである。


PS>dir d:\desktop\test1 | select mode,@{name="ファイル名は";expression={$_.name + "です"}}

Mode                                                        ファイル名は
----                                                        ------------
-a---                                                       test1.txtです
-a---                                                       test2.txtです

もともとあったスクリプトブロックにexpressionというキーを付け、加えてnameというキーでタイトルを追加している。キーと値のセットなので指定形式は@{}がついた連想配列形式になる。2個のキーと値の設定を1行で書いているので間にセミコロンを入れている。コマンドラインからではなくスクリプトファイルとして書くのならば以下のように書くのも良いかも。

001
002
003
004
005

$fileprop = @{
name
="ファイル名は"
expression={$_.name + "です"
}
}

dir d:\desktop\test1 | select mode,$fileprop

ちなみに、上記のハッシュテーブルは以下のように書いても良い。

001
002
003

$fileprop2 = @{}
$fileprop2.name="ファイル名は"
$fileprop2.expression={$_.name + "です"}

と、思っていたのだが・・・。
実際以下のようにどうみても同じに見える。
20101128003238

しかし、$fileprop2のほうは以下のようなエラーになる。

Select-Object : System.Management.Automation.PSObject を型 {System.String, Syst
em.Management.Automation.ScriptBlock} のいずれかに変換することはできません。
発生場所 D:\temp\b4b9f59f-3638-4969-9a96-d4d07f915788.ps1:16 文字:30
+ dir d:\desktop\test1 | select <<<<  mode,$fileprop2
    + CategoryInfo          : InvalidArgument: (:) [Select-Object]、NotSupporte
    dException
    + FullyQualifiedErrorId : DictionaryKeyUnknownType,Microsoft.PowerShell.Co
   mmands.SelectObjectCommand

だいぶ悩んで$fileprop1と$fileprop2の違いを調べたがどうにもわからない。
個人的にはバグ(bug)にしか思えないのだが・・・・。
とりあえず1の書き方をすればよいだけなので放置。

最後にSelect-Objectの使い方(オプション)を。集計プロパティを使っているが、コメントにしてあるAdd-Memberのほうを使ったも結果は同じになる。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017

$ps = Get-Process
$script:i = 0
#$ps | %{$i=0}{
#Add-Member -MemberType NoteProperty -Name No -Value (++$i) -InputObject $_
#}

$no = @{name="No";expression={(++$script:i)}}
$ps = $ps | select * ,$no
"先頭から3件"
$ps | select No,processname -First 3 | ft -AutoSize
"最後から3件"
$ps | select No,processname -Last 3 | ft -AutoSize
"0番目と12番目"
$ps | select No,processname -index 0,12
"0番目と12番目"
$ps | select -index 0,12
"modulesを展開"
$ps | select $name -ExpandProperty modules -First 1
</

結果は以下の通りなのだが、またしても色々と嵌った。(嵌ってばかりだ・・・)
まず、Indexパラメータ。なぜかエラーになる・・・。
どうやらPropertyパラメータと一緒に使えないらしい。
それじゃSelectじゃないと思うのだが・・・。

プロパティが連想配列の時(だけかは?)にExpandPropertyを指定すると中身を展開してくれる。これもPropertyとは併用できないようだ。(こちらはエラーにはならずに無視される)

今日もやけに疲れた・・・。

先頭から3件

No ProcessName
-- -----------
1 BaiduJPEngine
2 BWH32S
3 cmvMain


最後から3件

No ProcessName
-- -----------
65 WLIDSVC
66 WLIDSVCM
67 wmpnetwk


0番目と12番目
Select-Object : 引数 'System.Object[]' を受け入れる位置指定パラメーターが見つかりません。
発生場所 行:9 文字:13
+ $ps | select <<<<  No,processname -index 0,12
    + CategoryInfo          : InvalidArgument: (:) [Select-Object]、ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.Selec

0番目と12番目

Handles NPM(K)  PM(K)  WS(K) VM(M) CPU(s)   Id ProcessName
------- ------  -----  ----- ----- ------   -- -----------
     77      4  12884  69044   136  97.06 3180 BaiduJPEngine
    513     37 114288 130776   310 273.75 2936 firefox
modulesを展開

Name              : BaiduJPEngine
ModuleName        : BaiduJPEngine.exe
FileName          : C:\Program Files\Baidu\Type\BaiduJPEngine.exe
BaseAddress       : 4194304
ModuleMemorySize  : 86016
EntryPointAddress : 4201966
FileVersionInfo   : File:             C:\Program Files\Baidu\Type\BaiduJPEngine.exe
                    InternalName:     BaiduJPEngine
                    OriginalFilename: BaiduJPEngine.exe
                    FileVersion:      1, 0, 0, 20
                    FileDescription:  BaiduJP IME Engine
                    Product:          BaiduJP IME Engine
                    ProductVersion:   1, 0, 0, 20
                    Debug:            False
                    Patched:          False
                    PreRelease:       False
                    PrivateBuild:     False
                    SpecialBuild:     False
                    Language:         日本語 (日本)

Site              :
Container         :
Size              : 84
Company           : Baidu Inc.
FileVersion       : 1, 0, 0, 20
ProductVersion    : 1, 0, 0, 20
Description       : BaiduJP IME Engine
Product           : BaiduJP IME Engine

0 件のコメント:

コメントを投稿