首页 > 解决方案 > 在 Powershell 中删除具有序列化名称的文件夹

问题描述

我的问题可能\可能并不复杂,但我一直在摸索并寻找一种方法来做到这一点,但到目前为止还没有想出太多。

我有一个像这样的文件夹结构:

C:\
└───ParentFolder
    ├───ChildFolder1
    │   ├───SubFolderA_1
    │   ├───SubFolderA_2
    │   ├───SubFolderA_3
    │   ├───SubFolderA_4
    │   ├───SubFolderB_1
    │   ├───SubFolderB_2
    │   ├───SubFolderB_3
    │   └───SubFolderB_4
    └───ChildFolder2
        ├───SubFolderA_1
        ├───SubFolderA_2
        ├───SubFolderA_3
        ├───SubFolderA_4
        ├───SubFolderB_1
        ├───SubFolderB_2
        ├───SubFolderB_3
        └───SubFolderB_4

我正在寻找的是一个 PowerShell 脚本,它将利用“子文件夹”名称的序列化特性来删除旧版本,只留下最新的子文件夹。

使用上面的示例,这意味着脚本将删除 SubFolderA_1 到 SubFolderA_3 和 SubFolderB_1 到 SubFolderB_3,在 ChildFolders 中只留下 SubFolderA_4 和 SubfolderB_4。

有人知道这样做的方法吗?我在考虑对象排序 + 递归函数 + 模式匹配,但我似乎没有得到任何结果。顺便说一句,我是个PS菜鸟。

您的帮助将不胜感激。

标签: windowspowershell

解决方案


这是一种方法。[] 它的核心是Group-Objectcmdlet。经常被忽视的一件事是使用计算属性的能力与Select-Objectcmdlet 一样。

# fake reading in a list of directories
#    in real life, use Get-ChildItem -Directory
$DirList = @(
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderA_1'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderA_2'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderA_3'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderA_4'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderB_1'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderB_2'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderB_3'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder1\SubFolderB_4'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderA_1'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderA_2'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderA_3'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderA_4'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderB_11'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderB_22'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderB_3'
    [System.IO.DirectoryInfo]'C:\ParentFolder\ChildFolder2\SubFolderB_44'
)

$GroupedDirList = $DirList |
    # changed from sorting by the FullName to sorting by the trailing number
    #    thanks to LotPings for pointing out the glitch with multi-digit numbers
    Sort-Object {[int]$_.FullName.Split('_')[1]} |
    Group-Object {$_.FullName.Split('_')[0]}

foreach ($GDL_Item in $GroupedDirList)
    {
    $GDL_Item.Group |
        Select-Object -SkipLast 1 |
        ForEach-Object {
            # remove the quotes, the Write-Host, and the "$()" when you do this for real
            # can't use the "-WhatIf" parameter here since the dirs don't actually exist on my system
            Write-Host "Remove-Item -LiteralPath $($_.FullName) -Recurse -WhatIf"
            }

    '=' * 20
    }

输出 ...

Remove-Item -LiteralPath C:\ParentFolder\ChildFolder1\SubFolderA_1 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder1\SubFolderA_2 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder1\SubFolderA_3 -Recurse -WhatIf
====================
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder1\SubFolderB_1 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder1\SubFolderB_2 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder1\SubFolderB_3 -Recurse -WhatIf
====================
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder2\SubFolderA_1 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder2\SubFolderA_2 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder2\SubFolderA_3 -Recurse -WhatIf
====================
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder2\SubFolderB_3 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder2\SubFolderB_11 -Recurse -WhatIf
Remove-Item -LiteralPath C:\ParentFolder\ChildFolder2\SubFolderB_22 -Recurse -WhatIf
====================

推荐阅读