メモ
- Import-Csv で取得した PSCustomObject の配列を List に変換
- List.Sort(Comparer[PSCustomObject]) や List.Sort(Comparison<PSObject>) で PSCustomObject の NoteProperty の値を StrCmpLogicalW に渡して並べ替え
- 並べ替えに使用する列名は決め打ち
- CSVファイルにはあらかじめ並べ替え用の列を用意しておく
using namespace System.Collections.Generic
Set-StrictMode -Version Latest
Add-Type -Language CSharp -TypeDefinition @'
using System.Runtime.InteropServices;
namespace Win32Functions {
public class Win32StrCmpLW {
[DllImport(
"Shlwapi.dll", CharSet = CharSet.Unicode, EntryPoint = "StrCmpLogicalW"
)]
public static extern int StrCmpLogicalW(
[MarshalAs(UnmanagedType.LPWStr)] string psz1,
[MarshalAs(UnmanagedType.LPWStr)] string psz2
);
}
}
'@
class MyComparer : Comparer[PSCustomObject] {
[int]Compare([PSCustomObject]$x, [PSCustomObject]$y) {
$str1 = [string]$x.'SORT'
$str2 = [string]$y.'SORT'
return [Win32Functions.Win32StrCmpLW]::StrCmpLogicalW($str1, $str2);
}
}
$a = Import-Csv -Encoding Default -Path "${env:USERPROFILE}\Desktop\test.csv"
$b = [List[PSCustomObject]]@($a)
$b.Sort([MyComparer]::new())
$b | ConvertTo-Csv -NoTypeInformation | Set-Clipboard
- テスト用CSVデータの用意が難しい場合
- List.Sort(Comparison<PSObject>)
Set-StrictMode -Version Latest
$row0 = [PSCustomObject]@{sort = "0040A"; col1 = "1A"; col02 = "4B"}
$row1 = [PSCustomObject]@{sort = "02A"; col1 = "2A"; col02 = "2B"}
$row2 = [PSCustomObject]@{sort = "1A"; col1 = "3A"; col02 = "1B"}
$row3 = [PSCustomObject]@{sort = "30A"; col1 = "4A"; col02 = "3B"}
$a = @($row0, $row1, $row2, $row3)
$b = $a | ConvertTo-Csv -NoTypeInformation
$c = $b | ConvertFrom-Csv
Add-Type -Language CSharp -TypeDefinition @'
using System.Collections.Generic;
using System.Management.Automation;
using System.Runtime.InteropServices;
namespace MyNamespace {
public class MyClass {
[DllImport(
"Shlwapi.dll", CharSet = CharSet.Unicode, EntryPoint = "StrCmpLogicalW"
)]
public static extern int StrCmpLogicalW(
[MarshalAs(UnmanagedType.LPWStr)] string psz1,
[MarshalAs(UnmanagedType.LPWStr)] string psz2
);
public static int MySortStrCmpLW(PSObject obj1, PSObject obj2) {
string str1 = obj1.Properties[@"SORT"].Value.ToString();
string str2 = obj2.Properties[@"SORT"].Value.ToString();
return StrCmpLogicalW(str1, str2);
}
public static PSObject[] MySort(PSObject[] objs) {
List<PSObject> tmp = new List<PSObject>(objs);
tmp.Sort(MySortStrCmpLW);
return tmp.ToArray();
}
}
}
'@
$d = [MyNamespace.MyClass]::MySort($c);
$d