这是应用于powershell的"ASCIIbetical"命令与"Natural"命令的着名问题.为了能够以与资源管理器相同的方式对powershell进行排序,您可以在StrCmpLogicalW API上使用此包装器,它实际上为Windows资源管理器执行自然排序.这需要一些管道.
但是,这篇文章表明在python中有一个三线程实现的排序.人们希望Get-ChildItem cmdlet或至少文件系统提供程序可以具有内置的自然排序选项.不幸的是,他们没有.
所以这是一个问题,Powershell中最简单的实现是什么?简单来说,我的意思是编写的代码量最少,可能没有第三方/外部脚本/组件.理想情况下,我想要一个简短的 Powershell函数来为我做排序.
Rom*_*min 74
下面是一些非常简短的代码(只是$ToNatural脚本块),它使用正则表达式和匹配赋值器来处理带有空格的数字.然后我们像往常一样用填充数字对输入进行排序,结果实际上得到了自然顺序.
$ToNatural = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20) }) }
'----- test 1 ASCIIbetical order'
Get-Content list.txt | Sort-Object
'----- test 2 input with padded numbers'
Get-Content list.txt | %{ . $ToNatural }
'----- test 3 Natural order: sorted with padded numbers'
Get-Content list.txt | Sort-Object $ToNatural
Run Code Online (Sandbox Code Playgroud)
输出:
----- test 1 ASCIIbetical order
1.txt
10.txt
3.txt
a10b1.txt
a1b1.txt
a2b1.txt
a2b11.txt
a2b2.txt
b1.txt
b10.txt
b2.txt
----- test 2 input with padded numbers
1.txt
10.txt
3.txt
a 10b 1.txt
a 1b 1.txt
a 2b 1.txt
a 2b 11.txt
a 2b 2.txt
b 1.txt
b 10.txt
b 2.txt
----- test 3 Natural order: sorted with padded numbers
1.txt
3.txt
10.txt
a1b1.txt
a2b1.txt
a2b2.txt
a2b11.txt
a10b1.txt
b1.txt
b2.txt
b10.txt
Run Code Online (Sandbox Code Playgroud)
最后我们使用这个单行按照自然顺序按名称对文件进行排序:
Get-ChildItem | Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(20) }) }
Run Code Online (Sandbox Code Playgroud)
输出:
Directory: C:\TEMP\_110325_063356
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2011-03-25 06:34 8 1.txt
-a--- 2011-03-25 06:34 8 3.txt
-a--- 2011-03-25 06:34 8 10.txt
-a--- 2011-03-25 06:34 8 a1b1.txt
-a--- 2011-03-25 06:34 8 a2b1.txt
-a--- 2011-03-25 06:34 8 a2b2.txt
-a--- 2011-03-25 06:34 8 a2b11.txt
-a--- 2011-03-25 06:34 8 a10b1.txt
-a--- 2011-03-25 06:34 8 b1.txt
-a--- 2011-03-25 06:34 8 b2.txt
-a--- 2011-03-25 06:34 8 b10.txt
-a--- 2011-03-25 04:54 99 list.txt
-a--- 2011-03-25 06:05 346 sort-natural.ps1
-a--- 2011-03-25 06:35 96 test.ps1
Run Code Online (Sandbox Code Playgroud)
我更喜欢 @Larry Song 的答案,因为它的排序方式与 Windows 资源管理器完全一样。我尝试稍微简化一下,以减少干扰。
Add-Type -TypeDefinition @"
using System.Runtime.InteropServices;
public static class NaturalSort
{
[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string psz1, string psz2);
public static string[] Sort(string[] array)
{
System.Array.Sort(array, (psz1, psz2) => StrCmpLogicalW(psz1, psz2));
return array;
}
}
"@
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
$array = ('1.jpg', '10.jpg', '2.jpg')
[NaturalSort]::Sort($array)
Run Code Online (Sandbox Code Playgroud)
其输出:
1.jpg
2.jpg
10.jpg
Run Code Online (Sandbox Code Playgroud)
请允许我从另一个问题中复制并粘贴我的答案。
Windows 资源管理器正在使用 shlwapi.dll 中调用的旧 API,这StrCmpLogicalW就是看到不同排序结果的原因。
我不想填充零,所以写了一个脚本。
https://github.com/LarrysGIT/Powershell-Natural-sort
由于我不是 C# 专家,如果不整洁,请提出请求。
找到以下 PowerShell 脚本,它使用相同的 API。
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
}
Run Code Online (Sandbox Code Playgroud)
在下面查找测试结果。
PS> # Natural sort
PS> . .\NaturalSort.ps1
PS> Sort-Naturally -Array @('2', '1', '11')
1
2
11
PS> # If regular sort is being used
PS> @('2', '1', '11') | Sort-Object
1
11
2
PS> # Not good
PS> $t = ls .\testfiles\*.txt
PS> $t | Sort-Object
1.txt
10.txt
2.txt
PS> # Good
PS> Sort-Naturally -Array $t
1.txt
2.txt
10.txt
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22726 次 |
| 最近记录: |