My profile.ps1(3)


profile.ps1シリーズ第3弾です。

Where-Objectによるオブジェクトフィルタリングを簡略化


&{
$operators =
@("eq","ne","ge","gt","lt","le","like","notlike","match",
"notmatch","ieq","ine","ige","igt","ile","ilt","ilike",
"inotlike","imatch","inotmatch","ceq","cne","cge","cgt",
"clt","cle","clike","cnotlike","cmatch","cnotmatch")

foreach($operator in $operators)
{
$filter = @"
filter global:?$operator(`$property,`$value)
{
if(`$_.`$property -$operator `$value){`$_}
}
"
@
Invoke-Expression $filter
}
}

何の処理をしているのか

Where-Objectと比較演算子を組み合わせる処理を簡略化するフィルタを作成しています。「?eq」や「?like」という名前のフィルタが定義されます。

定義されたフィルタを確認するには、以下を入力してください。


ls function: | ?{$_.CommandType -eq "Filter"}


さて、フィルタの内容ですが、「?eq」は以下のように定義されます。


filter global:?eq($property,$value)
{
if($_.$property -eq $value){$_}
}

このフィルタを利用すると、このような↓処理が、


[コマンド] | ?{$_.XXX -eq YYY}

このように記述できるようになります。


[コマンド] | ?eq XXX YYY

なぜ作ったのか

Where-Objectでオブジェクトをフィルタリングする際、オブジェクトのプロパティ値に対して「-eq」「-ne」「-like」「-match」などを利用するケースが多いですが、毎回、スクリプトブロックで囲んだり「$_」を入力したりするのが面倒だなと思い、filterステートメントを利用して、スクリプトブロックや「$_」を省略するようにしました。

利用例:10KB以上で2007年以降に更新されたテキストファイルを取得する

通常はこのように↓書きますが、


ls *.txt | ?{$_.Length -ge 10KB} | ?{$_.LastWriteTime -ge "2007/01/01"}
このように↓書けます。

ls *.txt | ?ge Length 10KB | ?ge LastWriteTime 2007/01/01

私にとっては便利なのですが、一般的にはどうなんでしょ。(^^;