【发布时间】:2014-10-16 03:35:27
【问题描述】:
我尝试通过以下方式获取文件夹的文件及其子文件夹中的文件:
$files = Get-ChildItem "d:\MyFolders" -recurse
问题: 如何按文件夹层次结构对 $files 进行排序,这意味着最深的文件将位于数组的顶部,而最上面的文件将是最后一个元素?
P.S : 原因是如果我重命名某些文件夹而不是那些重命名的文件夹下的文件路径将无效。所以我想先处理最深的,然后移到上层的文件。
【问题讨论】:
我尝试通过以下方式获取文件夹的文件及其子文件夹中的文件:
$files = Get-ChildItem "d:\MyFolders" -recurse
问题: 如何按文件夹层次结构对 $files 进行排序,这意味着最深的文件将位于数组的顶部,而最上面的文件将是最后一个元素?
P.S : 原因是如果我重命名某些文件夹而不是那些重命名的文件夹下的文件路径将无效。所以我想先处理最深的,然后移到上层的文件。
【问题讨论】:
它没有具体按深度排序,但由于排序,它会将同一父级中的文件夹分组在一起。
$files | Sort-Object -Descending FullName | Select-Object FullName
如果确实需要按文件夹深度排序,可以这样:
$files | Select-Object FullName, @{Name="FolderDepth";Expression={$_.DirectoryName.Split('\').Count}} | Sort-Object -Descending FolderDepth,FullName
如果您想反转排序,只需删除 -Descending。
【讨论】:
这样做的一种方法是逐级解析您的目录:您从要检查的目录列表开始(最初,列表中只有您的起始文件夹)。 然后,为列表中的每个文件夹检查所有直接子文件夹:将文件写入结果文件,将文件夹添加到“下一个文件夹”列表中。
使用您的“下一个文件夹”列表再次执行此操作,直到此列表为空。
您将获得一个按深度排序的结果文件(好的,最深的文件是文件中的最后一个,因此您必须反转它,但无论如何它是按深度排序的:)
这可以通过这种方式递归完成:
function Parse-ByDepth ($dirs, $resultfile) {
$nextdirs=@()
# if you also want the folders names in the result file
# write their names in the result file
$dirs |% {
echo "$_" >> $resultfile
}
# Parse each directory in the list
foreach ($dir in $dirs){
# note that the get-childitem here is non recursive.
# only one level is checked.
Get-ChildItem $dir | % {
if ($_.getType().Name -eq "FileInfo") {
# If the item is a file, append it to the result file
echo "$($_.FullName)" >> $resultfile
}else {
# if it is a folder, add the folder path to the "next folders" list
$nextdirs+=$_.FullName
}
}
}
# once all the item of the current level have been parsed, check if the list is empty
if ($nextdirs.Length -gt 0) {
# if the list contains more folder, parse them
Parse-ByDepth $nextdirs $resultfile
}
}
那么,你可以这样调用函数:
$initdir=@("d:\MyFolders")
$resultfile=C:\result_by_depth.txt
Parse-ByDepth $initdir $resultfile
【讨论】: