如何控制使用get-childitem -recurse获取的项目的处理顺序?

4

尝试自学:当处理整个项目树时

get-childitem -recurse

我经常不得不从叶子级别到顶层进行操作(例如,删除文件和文件夹,修改树的上层然后尝试处理下层会出现问题。

为了解决这个问题,我不得不通过路径中分隔符的数量对整个集合进行排序,以便首先得到叶子级别,然后是树的上层:

$someFiles = Get-ChildItem -Recurse | Sort @{Expression={ ( $_.fullname | select-string "\\" -AllMatches ).matches.count }; Descending=$true }

这感觉不对-我有限的编程经验,但我知道如果我按正确的方式遍历树,则不需要进行这种昂贵和笨拙的排序。 但是,-recurse非常方便!

有什么更聪明的方法来做到这一点吗? 具体而言,是否有一种方法可以从叶子到上层遍历使用get-childitem获取的树,而无需对所有结果进行排序?

2个回答

6
你可以避免使用正则表达式,直接使用字符串分割方法。这种方法还能提高性能。
dir -recurse | sort -Property @{ Expression = {$_.FullName.Split('\').Count} } -Desc

结果:

TotalMilliseconds : 346.1253

vs...

Get-ChildItem -Recurse | Sort @{Expression={ ( $_.fullname | select-string "\\" -AllMatches ).matches.count }; Descending=$true }

结果:

TotalMilliseconds : 953.6606

这会加快事情的进展,而且mjolinor也是正确的,只有路径的长度应该起作用(子节点可能比其他节点短,但不能比它们的父节点短)。我只是想通过以正确的顺序输入集合并使用更好的树遍历方法来消除整个排序过程。这可能有点学术,但我很好奇 :-) - onupdatecascade

4

我只是使用全名的长度:

gci -recurse | sort @{expression = {$_.fullname.length}} -descending

在父容器之前,所有子项都会被排序。


1
我认为OP试图按文件夹深度而不是路径长度进行排序。 - Andy Arismendi
好的。但是如果您要删除整个文件夹树,并且只需要确保在删除所有子项之前不尝试删除父项,那么它将实现相同的功能。 - mjolinor
我不太明白那部分的意思,因为当父项被删除时,显然所有子项都会被删除,所以这有什么关系呢?然而,根据当前的示例,它是按照文件夹深度排序的,所以 C:\ShortName\A\B 将在数组中位于 C:\A really really long folder name 之前。 - Andy Arismendi
根据您用来执行删除的工具不同,如果文件夹中仍有子项,则可能会出现问题。至于“C:\A really really long folder name”在“C:\ShortName\A\B”之前列出的情况,如果您要全部删除它们,那么只要这两个文件夹的所有子项在该文件夹之前列出即可。 - mjolinor
是的,主要问题是如果您先删除(或更改)父文件夹,那么稍后在循环中它将抛出错误,尝试访问不再存在的内容。 - onupdatecascade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接