我正在尝试在文件夹中找到.sql文件,并根据上次写入时间对其进行过滤。 根据上次写入时间,我得到4个文件作为输出。
TestScript10.sql TestScript5.sql TestScript6.sql TestScript7.sql
现在,当我的命令尝试执行sort-object时,我看到顶部的Testscript10而不是TestScript5,我该如何解决这个问题?
我的代码"
$File= Get-ChildItem $FileLocation -Filter *.sql | Where-Object {$_.LastWriteTime -gt $datetime} | Sort-Object Name
$文件输出
[DBG]:PS SQLSERVER:>> $文件
Directory: C:\SQLScripts
模式LastWriteTime长度名称
---- ------------- ------ ----
-a --- 5/22/2014 10:20 AM 61 TestScript10.sql
-a --- 5/22/2014 10:16 AM 60 TestScript5.sql
-a --- 5/22/2014 10:24 AM 66 TestScript6.sql
-a --- 5/22/2014 10:10 AM 24 Testscript7.sql
答案 0 :(得分:5)
感谢您对我的问题的所有建议。简化建议后,下面的代码适用于我的情况。这有助于我按照Windows资源管理器的自然顺序进行排序。
$ToNatural= { [regex]::Replace($_, '\d+',{$args[0].Value.Padleft(20)})}
$File= Get-ChildItem $FileLocation -Filter *.sql | Where-Object {$_.LastWriteTime -gt $datetime} | Sort-Object $ToNatural
答案 1 :(得分:4)
这样的事情:
| sort-object {[int]($_.basename -replace '\D')}
答案 2 :(得分:2)
嗯...终于明白了。
Windows资源管理器在排序字符串时在shlwapi.dll中使用称为StrCmpLogicalW的遗留API,这就是我们看到不同排序结果的原因。
我不想使用padding零方法,所以写一个脚本。
https://github.com/LarrysGIT/Powershell-Natural-sort
由于我不是C#专家,因此赞赏拉请求。
查找以下powershell脚本,它使用相同的API。
function Sort-Naturally
{
PARAM(
[string[]]$strArray
)
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());
}
}
}
'@
return [NaturalSort.NaturalSort]::Sort($strArray)
}
在下面找到测试结果。
PS> # Natural sort
PS> . .\NaturalSort.ps1
PS> Sort-Naturally -strArray @('2', '1', '11')
1
2
11
PS> # If regular sort is used
PS> @('2', '1', '11') | Sort-Object
1
11
2
和
PS> # Not good
PS> $t = (ls .\Scripts*.txt).name
PS> $t | Sort-Object
Scripts1.txt
Scripts10.txt
Scripts2.txt
PS> # Good
PS> Sort-Naturally -strArray $t
Scripts1.txt
Scripts2.txt
Scripts10.txt
答案 3 :(得分:0)
我更喜欢@mjolinor解决方案,因为它显示了PowerShell中排序的强大功能。但是,如果你想用注释中提到的前缀“修复”文件名:
Get-ChildItem Test*.sql |
Rename-Item -NewName { 'TestScript{0:D2}.sql' -f [int]($_.BaseName -replace '\D') }
重命名后,文件将按预期排序。如果您需要两位以上 - 只需更改格式化({0:D#}
)。