I am trying to find .sql files in a folder and filtering them based on the last write time. Based on the last write time I got 4 files as output.
TestScript1
Hm... finally figure it out.
Windows explorer is using a legacy API in shlwapi.dll called StrCmpLogicalW when sorting strings.
I don't want to use padding zeros, so wrote a script.
https://github.com/LarrysGIT/Powershell-Natural-sort
Find the following powershell script, it using the same API. You may need to check the latest code from the repo as I am not updating here always.
function Sort-Naturally
{
PARAM(
[System.Collections.ArrayList]$Array,
[switch]$Descending
)
Add-Type -TypeDefinition @'
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace NaturalSort {
public static class NaturalSort
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
public static System.Collections.ArrayList Sort(System.Collections.ArrayList foo)
{
foo.Sort(new NaturalStringComparer());
return foo;
}
}
public class NaturalStringComparer : IComparer
{
public int Compare(object x, object y)
{
return NaturalSort.StrCmpLogicalW(x.ToString(), y.ToString());
}
}
}
'@
$Array.Sort((New-Object NaturalSort.NaturalStringComparer))
if($Descending)
{
$Array.Reverse()
}
return $Array
}
Find the test results below.
PS> # Natural sort
PS> . .\NaturalSort.ps1
PS> Sort-Naturally -Array @('2', '1', '11')
1
2
11
PS> # If regular sort is used
PS> @('2', '1', '11') | Sort-Object
1
11
2
And,
PS> # Not good
PS> $t = (ls .\Scripts*.txt).name
PS> $t | Sort-Object
Scripts1.txt
Scripts10.txt
Scripts2.txt
PS> # Good
PS> Sort-Naturally -Array $t
Scripts1.txt
Scripts2.txt
Scripts10.txt