如何按照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的。