【问题标题】:Avoid recursively fetching specific folders in PowerShell避免在 PowerShell 中递归获取特定文件夹
【发布时间】:2013-01-18 22:23:53
【问题描述】:

我有一个包含多个项目的 Visual Studio 解决方案。作为清理的一部分,我使用以下脚本清理了 bin 和 obj 文件夹。

Get-ChildItem -path source -filter obj -recurse | Remove-Item -recurse
Get-ChildItem -path source -filter bin -recurse | Remove-Item -recurse

这非常有效。但是,我有一个基于文件的数据文件夹,其中包含大约 600,000 个子文件夹,位于名为 FILE_DATA 的文件夹中。

上面的脚本需要很长时间,因为它遍历了所有这 600,000 个文件夹。

递归遍历删除bin和obj文件夹时需要避开FILE_DATA文件夹。

【问题讨论】:

    标签: powershell get-childitem


    【解决方案1】:

    这是一种更有效的方法,可以满足您的需要——跳过您想要排除的子树:

    function GetFiles($path = $pwd, [string[]]$exclude)
    {
        foreach ($item in Get-ChildItem $path)
        {
            if ($exclude | Where {$item -like $_}) { continue }
    
            $item
            if (Test-Path $item.FullName -PathType Container)
            {
                GetFiles $item.FullName $exclude
            }
        }
    } 
    

    此代码改编自 Keith Hill 对this post 的回答;我的贡献是修复了一个错误并进行了少量重构;您将在我对同一个 SO 问题的回答中找到完整的解释。

    这个调用应该做你需要的:

    GetFiles -path source -exclude FILE_DATA
    

    如需更悠闲的阅读,请查看我在 Simple-Talk.com 上的文章,其中讨论了这一点以及更多内容:Practical PowerShell: Pruning File Trees and Extending Cmdlets

    【讨论】:

    • 这解决了我的问题。我做了一些小改动,让它对我有用。我会尽快发布我的代码。谢谢。
    • function RemoveBinAndObj($path = $pwd, [string[]]$remove, [string[]]$exclude) { foreach ($item in Get-ChildItem $path) { if ($exclude | Where {$item -like $_}) { continue } if ($remove | Where {$item -like $_}) { Write-Host "Removing " + $item.FullName Remove-Item $item.FullName -Recurse } if (Test-Path $item.FullName -PathType Container) { RemoveBinAndObj $item.FullName $remove $exclude } } }
    • 对不起,Graimer 有一个更简洁和最好的解决方案。您的解决方案也很完美。它解决了这个问题。但 Graimer 的解决方案更简洁,执行速度也更快。
    • 既然你现在声明你只对直系子女感兴趣,那么我同意——@Graimer 的特殊情况解决方案更合适。我的解决方案解决了任何后代的更一般情况,而不仅仅是直系子女。
    【解决方案2】:

    如果 FILE_DATA 文件夹是 $source 的子文件夹(不是更深),请尝试:

    $source = "C:\Users\Frode\Desktop\test"
    Get-Item -Path $source\* -Exclude "FILE_DATA" | ? {$_.PSIsContainer} | % {
        Get-ChildItem -Path $_.FullName -Filter "obj" -Recurse | Remove-Item -Recurse
        Get-ChildItem -Path $_.FullName -Filter "bin" -Recurse | Remove-Item -Recurse
    }
    

    【讨论】:

    • 该文件夹是来自源的大子文件夹。这有效..但它仍然在 FILE_DATA 文件夹中。
    • 大子文件夹?前任。 $source = c:\testFILE_DATA is c:\test\FILE_DATA?
    • 现在测试了。当我使用 $source = c:\test 时它没有删除 FILE_DATA 但在运行 PS 2.0 时它并不关心 -Include 所以它删除了几乎所有其他内容:P 现在修复它
    • 这太棒了.. 效果很好.. 非常感谢。
    • 对于那些只想删除解决方案项目文件夹中的所有 binobj 文件夹的用户,只需将第一行替换为 Get-ChildItem -Directory | % {(-Directory 标志是 PowerShell 3 的一部分) .如果您只想从直接子级中删除 binobj,请在管道前放置 -Recurse 标志。此外,-Path $_.FullName 可以缩短为 $_
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多