如何按照Windows资源pipe理器的相同方式按文件名进行sorting?

这是着名的问题“ASCIIbetical”顺序与“自然”顺序适用于PowerShell。 为了能够像浏览器一样在PowerShell中进行sorting,可以在StrCmpLogicalW API上使用这个包装器 ,它实际上执行Windows资源pipe理器的自然sorting。 这将需要一些pipe道。

但是, 这篇文章build议在python中有三种types的实现。 人们会希望Get-ChildItem cmdlet或至less文件系统提供程序可以有内置的自然sorting选项。 不幸的是,他们没有。

那么这里是一个问题,Powershell中这个最简单的实现是什么? 简单来说,我的意思是写最less量的代码,并且可能没有第三方/外部脚本/组件。 理想情况下,我想要一个短的 Powershell函数,可以为我sorting。

这是一些非常短的代码(只是$ToNatural脚本块),用正则expression式和匹配评估器来执行这个技巧,以便用空格填充数字。 然后,我们按照平常的方式对input进行填充,然后实际得到自然顺序。

 $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 

输出:

 ----- 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 

最后,我们使用这个单行按自然顺序排列文件名称:

 Get-ChildItem | Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(20) }) } 

输出:

  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 

从python到PowerShell的翻译工作得很好:

 function sort-dir { param($dir) $toarray = { @($_.BaseName -split '(\d+)' | ?{$_} | % { if ([int]::TryParse($_,[ref]$null)) { [int]$_ } else { $_ } }) } gci $dir | sort -Property $toarray } #try it mkdir $env:TEMP\mytestsodir 1..10 + 100..105 | % { '' | Set-Content $env:TEMP\mytestsodir\$_.txt } sort-dir $env:TEMP\mytestsodir Remove-Item $env:TEMP\mytestsodir -Recurse 

当您使用代理function方法时,您可以做得更好。 你添加-natur参数给Sort-Object ,你有非常漂亮的解决scheme。

更新 :首先我很惊讶,PowerShell以这种方式处理比较数组。 当我尝试创buildtesting文件("a0", "a100", "a2") + 1..10 + 100..105 | % { '' | Set-Content $env:TEMP\mytestsodir\$_.txt } ("a0", "a100", "a2") + 1..10 + 100..105 | % { '' | Set-Content $env:TEMP\mytestsodir\$_.txt } ("a0", "a100", "a2") + 1..10 + 100..105 | % { '' | Set-Content $env:TEMP\mytestsodir\$_.txt } ,结果certificate它不起作用。 所以,我认为没有优雅的解决scheme,因为PowerShell是静态的,而Python是dynamic的。