2010年11月25日木曜日

◆Compare-Objectは難しい?

Compare-Object、エイリアスはCompare

ちなみに、これまで使った限りでは、XXXX-ObjectのエイリアスはXXXXだ。
New-Objectだけ(かどうかは調べていないが)はなぜかNewではだめ。
Compare-Objectにはdiffというエイリアスもあるのでそちらのほうが通りがよいかもしれない。

で、本題だが、Compare-Objectを使って以下のありがちなコードを書いてみた。

001
002
003
004
005

$oldps = ps
notepad
 
$newps = 
ps
diff
 $oldps $newps | 
gm
diff
 $oldps $newps
 

結果は
 20101125212044

まぁ、予想通りの結果だ。
説明するまでもないかもしれないが(私はよく判っていなかった)、「=>」の意味するところは、InputObjectに表示されたものが、diffの引数の右側(第2引数)にしか無いよという事。

問題なのは、このスクリプトの4行目と5行目を単純に入れ替えた時だ。
すると、結果はこうなる。
20101125214656

@@ Get-Memberはどこへ? 
 
Tee-Objectなんかしても何やらおかしい。
20101125233628

4行目のコメントをはずすと、

20101125233918

GetTypeの表示の他に6行目のGet-Memberが有効になる。

果たして、BUGなのか私の知らない仕様が存在するのか・・・・。

そもそもCompare-Objectのヘルプによると、このコマンドレットのパイプライン出力は無いと書いてある。
なので、出力されるのがたまたま(BUG?)で出力されないのが正しいのかもしれない。

というわけで、Cpmpare-Objectのパイプライン出力には触れないのが得策の様だ。
Cpmpare-Objectにはパイプライン出力用のpassthruスイッチが用意されているのでそちらを使うのがまっとうな使い方なのだろう。
20101125235734

比較して相違のあったオブジェクト(ここではメモ帳のプロセスオブジェクト)がやって くる。
ただし、ここでもTee-Objectはダメっぽい。というか私が何か理解不足なのか。

20101126000317

個々のプロパティが一つのクラスとして表示されている。
ただ、そのどれもがProcessクラスというのはどう考えてもおかしいような・・・。

ん~、Teeも使わないことにする。

色々と紆余曲折し悩んだが、最後にまっとうなCompare-Objectのサンプルを。
上記のPassthruでやってくるProcessオブジェクト、型としてはProcessなのだが、Powershellが独自にプロパティを追加しているようだ。
以下でそれを表示してみる。

001
002
003
004
005
006
007
008
009
010

$oldps = ps
notepad
 
$newps = 
ps
diff
 $oldps $newps -PassThru | Set-Variable result
$result | gm | Set-Variable psprocess

ps | gm | Set-Variable normalprocess

diff $psprocess $normalprocess -Property name,membertype 
$result.Kill(
)

結果は以下の通り。

20101126004021

例の差異を表す「<=」がNotePropertyとして追加されているのが判る。

あぁー、なんか疲れた。

2 件のコメント:

  1. Compare-Objectが既定では出力がないというのは、ヘルプの間違いですね

    Get-Memberの出力は無くなったのではなく、Compare-Objectの出力書式に合わせられた結果、
    InputObject、SideIndicatorプロパティを持たない為、見かけ上表示されないだけです

    ので、Get-Memberの出力の分だけ改行されますし、これらと同名のプロパティを追加させれば、それが出力されます

    compare $a $b
    compare $a $b | gm | Add-Member NoteProperty InputObject 1 -PassThru

    これはTee-Objectを使った場合も同じです

    compare $a $b | tee -Variable c
    $c | gm | Add-Member NoteProperty InputObject 1 -PassThru

    私も出力書式の仕様は詳しくないので、どうしてそうなるのか、までは説明できませんが・・・

    返信削除
  2. S.K.さんコメントありがとうございます。

    確かにそのようですね。Out-Hostを追加することで期待通りになるのを確認しました。

    どうもCompare-Objectの問題ではなく、そこで出力されるPSCustomObjectの扱いに問題があるようですね。

    別稿で纏めてみたいと思います。

    返信削除