Home >
Windows にまつわる e.t.c.
PowerShell の Sort-Object Tips
データーを sort すると言えば、その昔は sort.exe、最近ならば Excel って方が多いのではないでしょうか?
実は PowerShell の Sort-Object コマンドレットって意外と優秀だったりします。
PowerShell のコマンドレットなので、オブジェクトを sort するのが仕事なのですが、Import-Csv で
CSV ファイルを読んだり、Get-xxx コマンドレットで取得したデータも sort 出来ますね。
Sort-Object ではこんな事が出来ます。
■ 1プロパティを指定した sort
■ 複数プロパティを指定した 昇順 sort
■
複数プロパティを指定した 降順 sort
■ プロパティ別に照準/降順を指定した sort
■ 重複排除
■ IPv4 アドレス sort
■ 数字 sort
1プロパティを指定した 昇順 sort
まずは sort 対象の CSV ファイル(HostRole.csv)を読み込みこんで表示します。
# CSV データーの読み込み $CSVData = Import-Csv .\HostRole.csv
# CSV
データーの表示 $CSVData | ft * -AutoSize |
PS C:\Temp> # CSV データーの読み込み
PS C:\Temp> $CSVData = Import-Csv .\HostRole.csv
PS C:\Temp>
PS C:\Temp> # CSV データーの表示
PS C:\Temp> $CSVData | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06627-ap 172.18.42.54 Project001-domain004 ADDS
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a04804-db 10.20.42.201 Project001-db001 DB
a04802-db 10.20.42.202 Project001-db002 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04902-db 10.20.42.212 Project001-db012 DB
a03429-ap 10.20.2.116 Project001-deploy002 DPL
a06513-ap 10.20.42.93 Project001-bt003 BT
a06628-ap 10.20.42.94 Project001-bt004 BT
|
これを Role で sort してみます。
# Role で sort Sort-Object -Property Role |
PS C:\Temp> $CSVData | Sort-Object -Property Role | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06627-ap 172.18.42.54 Project001-domain004 ADDS
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a06513-ap 10.20.42.93 Project001-bt003 BT
a06628-ap 10.20.42.94 Project001-bt004 BT
a04802-db 10.20.42.202 Project001-db002 DB
a04804-db 10.20.42.201 Project001-db001 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04902-db 10.20.42.212 Project001-db012 DB
a03429-ap 10.20.2.116 Project001-deploy002 DPL
|
複数プロパティを指定した 昇順 sort
複数プロパティを sort key に指定する場合は、-Property にプロパティをカンマ区切りで複数書きます。
# Role + CNAME で 昇順 sort Sort-Object -Property Role, CNAME |
Sort-Object は sort に、-Property は省略可能なので、このように省略できます
PS C:\Temp> $CSVData | sort Role, CNAME | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06627-ap 172.18.42.54 Project001-domain004 ADDS
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a06513-ap 10.20.42.93 Project001-bt003 BT
a06628-ap 10.20.42.94 Project001-bt004 BT
a04804-db 10.20.42.201 Project001-db001 DB
a04802-db 10.20.42.202 Project001-db002 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04902-db 10.20.42.212 Project001-db012 DB
a03429-ap 10.20.2.116 Project001-deploy002 DPL
|
複数プロパティを指定した 降順 sort
Sort-Object は昇順が default なので、降順 sort する場合は -Descending を指定します。
# 降順 sort sort Role, CNAME -Descending |
PS C:\Temp> $CSVData | sort Role, CNAME -Descending | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a03429-ap 10.20.2.116 Project001-deploy002 DPL
a04902-db 10.20.42.212 Project001-db012 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04802-db 10.20.42.202 Project001-db002 DB
a04804-db 10.20.42.201 Project001-db001 DB
a06628-ap 10.20.42.94 Project001-bt004 BT
a06513-ap 10.20.42.93 Project001-bt003 BT
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a06627-ap 172.18.42.54 Project001-domain004 ADDS
a06512-ap 172.18.42.53 Project001-domain003 ADDS
|
プロパティ別に照準/降順を指定した sort
-Descending は全ての -Property に対して影響するので、プロパティ別の昇順降順指定は出来ません。
プロパティ別に降順照準を指定する場合は、ソート条件をハッシュ テーブルにして -Property に渡します。
プロパティは Expression キーで指定し、昇順降順は Ascending キーまたは Descending キーを $true/$false
指定します。
# Role(降順) + CNAME(昇順) sort sort
@{Expression="Role";Descending=$true},
@{Expression="CNAME";Descending=$false} |
PS C:\Temp> $CSVData | sort @{Expression="Role";Descending=$true}, @{Expression="CNAME";Descending=$false} | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a03429-ap 10.20.2.116 Project001-deploy002 DPL
a04804-db 10.20.42.201 Project001-db001 DB
a04802-db 10.20.42.202 Project001-db002 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04902-db 10.20.42.212 Project001-db012 DB
a06513-ap 10.20.42.93 Project001-bt003 BT
a06628-ap 10.20.42.94 Project001-bt004 BT
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06627-ap 172.18.42.54 Project001-domain004 ADDS
|
重複排除
重複排除は、-Unique を指定します。
# Role で重複排除 sort Role -Unique |
PS C:\Temp> $CSVData | sort Role -Unique | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a06513-ap 10.20.42.93 Project001-bt003 BT
a04802-db 10.20.42.202 Project001-db002 DB
a03429-ap 10.20.2.116 Project001-deploy002 DPL
|
IPv4 アドレス sort
IPv4 アドレスは、文字列として扱われるので、そのまま sort 残念な結果になってしまいます。
# IP アドレスで単純 sort sort IPAddress |
PS C:\Temp> $CSVData | sort IPAddress | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a03429-ap 10.20.2.116 Project001-deploy002 DPL
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a04804-db 10.20.42.201 Project001-db001 DB
a04802-db 10.20.42.202 Project001-db002 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04902-db 10.20.42.212 Project001-db012 DB
a06513-ap 10.20.42.93 Project001-bt003 BT
a06628-ap 10.20.42.94 Project001-bt004 BT
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06627-ap 172.18.42.54 Project001-domain004 ADDS
|
IPv4
アドレスは、System.Versionと同じ体系([Major].[Minor].[Revision].[Build])なので、こいつにキャストすれば意図した順番に
sort 出来ます。
キャストする場合は、スクリプトブロックで記述します。
# IPv4 アドレス sort sort {[System.Version]$_.IPAddress} |
PS C:\Temp> $CSVData | sort {[System.Version]$_.IPAddress} | ft * -AutoSize
HostName IPAddress CNAME Role
-------- --------- ----- ----
a03429-ap 10.20.2.116 Project001-deploy002 DPL
a06513-ap 10.20.42.93 Project001-bt003 BT
a06628-ap 10.20.42.94 Project001-bt004 BT
a04813-ap 10.20.42.101 Project001-ap001 AP-A
a04812-ap 10.20.42.102 Project001-ap002 AP-A
a05029-ap 10.20.42.103 Project001-ap003 AP-A
a05028-ap 10.20.42.104 Project001-ap004 AP-A
a04811-ap 10.20.42.121 Project001-ap021 AP-B
a04810-ap 10.20.42.122 Project001-ap022 AP-B
a04927-ap 10.20.42.124 Project001-ap024 AP-B
a05023-ap 10.20.42.125 Project001-ap025 AP-B
a05022-ap 10.20.42.126 Project001-ap026 AP-B
a05021-ap 10.20.42.127 Project001-ap027 AP-B
a05020-ap 10.20.42.128 Project001-ap028 AP-B
a05019-ap 10.20.42.129 Project001-ap029 AP-B
a05018-ap 10.20.42.130 Project001-ap030 AP-B
a05017-ap 10.20.42.131 Project001-ap031 AP-B
a05125-ap 10.20.42.133 Project001-ap033 AP-B
a06514-ap 10.20.42.193 Project001-admin003 ADMIN
a06629-ap 10.20.42.194 Project001-admin004 ADMIN
a04804-db 10.20.42.201 Project001-db001 DB
a04802-db 10.20.42.202 Project001-db002 DB
a04904-db 10.20.42.211 Project001-db011 DB
a04902-db 10.20.42.212 Project001-db012 DB
a06512-ap 172.18.42.53 Project001-domain003 ADDS
a06627-ap 172.18.42.54 Project001-domain004 ADDS
|
数字 sort
スクリプトの中で扱っている数値であれば、数値属性になっているのでそののまま sort しても問題はないのですが、CSV
を読み込んだデーターの場合は、数値ではなく数字文字列になっています。
このため、数値だと思って sort すると IP アドレスと同様に残念な結果になります。
これを避けるには、数値にキャストして sort します。
# 数字文字列 sort sort {[int]$_.Index} |
ソート済みのオブジェクトを CSV に出力
最後にソート済みのオブジェクトを CSV に出力すれば処理完了ですね。
# sort $SortData = $CSVData | sort {[Version]$_.IPAddress}
# CSV 出力 $SortData | Export-Csv .\SortHostRole.csv |
関連情報
PowerShellのSort-ObjectコマンドレットでIPアドレスのソートを行う - 素敵なおひげですね
http://stknohg.hatenablog.jp/entry/2017/02/15/230954
オブジェクトをユニークにして存在数を付加する PowerShell フィルター
http://www.vwnet.jp/Windows/PowerShell/2016092401/CountUnique.htm
Copyright © MURA
All rights reserved.