IPアドレスを含んだCSVファイルなどを読み込んでIPアドレス順にソートする。
IPAddressクラスなんかにキャストしたら簡単にできるのかと思ったのだがそうも行かないようだ。(気づかないだけかもしれないが)
とりあえず力技でやって見る。
それぞれのオクテットをプロパティとして持つオブジェクトを作ってそれでソートしてやれば良いだろう。
分割するのはSplitでも良いと思うのだが、ここでは正規表現を使ってみた。
(IPAddressクラスのGetAddressBytes()なんかでも出来る)
001 002 003 004 005 006 | $addrs = "10.2.10.2","10.30.10.3","10.30.10.130","10.210.1.1","10.1.244.2" $addrs | %{$_ -match '(\d+).(\d+).(\d+).(\d+)' | Out-Null 1..4 | %{$matches[$_] = [int]$matches[$_]} New-Object PsObject -Property $matches} | sort {$_."1",$_."2",$_."3",$_."4" } | select @{name="IPAddress";expression={$_."0"}} |
こんな感じで良いのかと思ったのだが結果を見るとうまくいっていない。プロパティが文字列として扱われている。$matchesを直接プロパティに設定したのではダメっぽい(理由は今ひとつ分かっていないが)
仕方が無いのでプロパティを一つずつ設定することにした。
001 002 003 004 005 006 007 | $addrs = "10.2.10.2","10.30.10.3","10.30.10.130","10.210.1.1","10.1.244.2" $addrs | %{$_ -match '(\d+).(\d+).(\d+).(\d+)' | Out-Null 1..4 | %{$matches[$_] = [int]$matches[$_]} 0..4 | %{$props=@{}}{$props."p$($_)" = $Matches[$_]} New-Object PsObject -Property $props } | sort p1,p2,p3,p4 | select @{name="IPAddress";expression={$_.p0}} |
今度は良さそうだ。
次は考え方を変えて文字列のままソートしてみる。
文字列の場合はそれぞれのオクテットの桁数を3桁に揃えてやれば良いだろう。
001 002 003 004 | $addrs = "10.2.10.2","10.30.10.3","10.30.10.130","10.210.1.1","10.1.244.2" $addrs | %{"{0:000}.{1:000}.{2:000}.{3:000}" -f @([int[]]$_.split('.'))} | sort | %{"{0}.{1}.{2}.{3}" -f @([int[]]$_.split('.'))} |
こっちのほうがいくらかスマートかな?
調べていたら、もっと簡単な方法もあった。
若干裏技的な気もするが、Versionクラスにキャストしてソートすると簡単だ。
001 002 | $addrs = "10.2.10.2","10.30.10.3","10.30.10.130","10.210.1.1","10.1.244.2" $addrs | % { [Version] $_ } | Sort | % { $_.toString() } |
だいぶスマートになった。
0 件のコメント:
コメントを投稿