小ネタです。
こちらの記事を見てPowerShellでもやってみました。
サンプルデータ
元記事と同じデータ(test.txt
)を使います。
192.168.0.102 192.168.0.8 192.168.0.97 192.168.0.68 192.168.0.99 192.168.0.66 192.168.0.24
普通のソート結果はこんな感じです。
単純な文字列のソートになるので元記事同様に欲しい形にはなりません。
version-sort
こちらは、私は最初思いつかなかったのですが、牟田口先生があっさり書いてくれました。流石です。
cat .\test.txt | sort {[Version]$_}
結果はこちら。
解説
PowerShellのsort(Sort-Object)
では-Property
パラメーターでソートに使うプロパティを指定することができ、そのプロパティにスクリプトブロックによる式を指定することができます。
sort {[Version]$_}
の部分をより正確に書くと、
Sort-Object -Property { [Version]$_ }
となり、入力値の文字列$_
(192.168.0.102
など)をSystem.Version
クラスにキャストした結果でソートできる様になります。
これは、.NET Frameworkのバージョン指定が、[Major].[Minor].[Revision].[Build]とIPアドレスと同じ書式なため利用できる方法です。
各オクテットごとにソート
こちらは私が最初に思いついた方法です。
元記事同様に各オクテット順でソートします。
cat .\test.txt | sort (0..3|%{[ScriptBlock]::Create("[int]$`_.Split('.')[$_]")})
結果はこちら。
解説
上記の
(0..3|%{[ScriptBlock]::Create("[int]$`_.Split('.')[$_]")})
の部分を展開すると、
{[int]$_.Split('.')[0]}, {[int]$_.Split('.')[1]}, {[int]$_.Split('.')[2]}, {[int]$_.Split('.')[3]}
となり、最終的なコマンドは
Sort-Object -Property ({[int]$_.Split('.')[0]}, {[int]$_.Split('.')[1]}, {[int]$_.Split('.')[2]}, {[int]$_.Split('.')[3]})
となります。
-Property
では入力値の文字列$_
(192.168.0.102
など)を.
でスプリットした結果(各オクテット)を順にソート対象にしています。
2017/02/17追記 別解
元のデータが文字列なので、桁数が揃っていれば期待したソートをさせることが可能です。
なので別解として、
cat .\test.txt | sort { -join $_.Split('.').PadLeft(3)}
も可能です。
この方法では入力文字列を、
192168 0102 192168 0 8 192168 0 97 192168 0 68 192168 0 99 192168 0 66 192168 0 24
の様に変換して桁数を揃えています。
最後に
とりあえずこんな感じです。
PowerShellのソートはかなり自由度が高く、何でもありな感じがしますね。