【问题标题】:PowerShell strips recursive variable of its full pathPowerShell 剥离其完整路径的递归变量
【发布时间】:2019-01-19 01:10:30
【问题描述】:

我有一个遍历目录树的简单脚本。

function GetSubFolders([IO.DirectoryInfo]$folder) {
    Write-Host "Getting folder $folder"

    Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_ }
}

如果我调用GetSubFolders "c:\temp",它对于在 c:\temp: 中找到的每个子目录都会失败

Get-ChildItem : 找不到路径 'C:\WINDOWS\system32\somefolder

其中“somefolder”是 c:\temp 的子目录。变量$_ 明明是System.IO.DirectoryInfo 对象,但是为什么它被剥离了绝对路径,突然相对于当前目录c:\windows\system32?请注意,进入此方法后,它会正确输出

获取文件夹 c:\temp

这意味着它只工作一次,所以 Get-ChildItem 接受 DirectoryInfo 对象作为参数不会有问题。

【问题讨论】:

  • 您尝试使用仅匹配 Get-ChildItem.-Name 属性的“按名称”或“按位置”的对象 [grin] 看看此[io.directoryinfo]'C:\temp' | Select-Object -Property *,然后将其与此(Get-Help Get-ChildItem -Parameter *).Name 中的列表进行比较。请注意第一个对象中缺少任何 -Path 或 -LiteralPath` 属性名称。
  • 为什么它只能工作一次,这就是我感到困惑的原因。
  • 我不知道……对我来说似乎总是失败。

标签: powershell recursion get-childitem


【解决方案1】:
function GetSubFolders([IO.DirectoryInfo]$folder) {
    Write-Host "Getting folder $folder"
    Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_.FullName }
}

我认为您正在寻找 FullName 的属性。

【讨论】:

  • 这是我用来解决问题的方法,但如果 $_ 是一个目录信息对象,为什么还要 .FullName 呢?
  • powershell 处理对象。每个对象都有多个属性(通常)。所以他们中的一些人应该在像你这样的特定场景中返回其中一个(属性)作为默认值。在您的情况下,默认值是名称而不是全名。
  • 其他方式,因为您的构造可能会在开头使用 $folder.fullname 而不是在末尾使用 $_.fullname
  • 另一种方式:(gci $folder -recurse | where {$_.mode -like 'd*'}).fullname |排序
【解决方案2】:

尝试使用

Get-ChildItem -Path 'c:\temp' -Recurse -Directory

目录标志将在 V3 中可用。如果你不使用 V3,你也可以使用

Get-ChildItem -Path 'c:\temp' -Recurse | ? { $_.PSIsContainer }

编辑:

目录标志在 V3 中可用。 感谢 Ansgar Wiechers 的评论。

【讨论】:

    【解决方案3】:

    使用递归/管道的解决方案效率很低。正如其他建议更好地使用 GCI 的 -recurse 开关。但也有循环/队列的替代方案。这适用于任何类型的树对象 - 循环遍历根节点的子节点,如果子节点有更多节点 - 将其添加到队列中。

    function Get-SubfolderQueue { param([IO.directoryinfo]$dir)
    
     $queue = New-Object System.Collections.Queue
     $queue.Enqueue($dir)
    
     While($queue.Count -gt 0) {
        $curr = $queue.Dequeue()
        foreach ($d in $curr.GetDirectories()) {
            Write-Output $d
            If($d.GetDirectories().Count -gt 0) { 
               $queue.Enqueue($d)
             }
        }
     }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-19
      • 2020-04-27
      • 1970-01-01
      相关资源
      最近更新 更多