Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 正在删除Powershell中具有序列化名称的文件夹_Windows_Powershell - Fatal编程技术网

Windows 正在删除Powershell中具有序列化名称的文件夹

Windows 正在删除Powershell中具有序列化名称的文件夹,windows,powershell,Windows,Powershell,我的问题可能并不复杂,但我一直在挠头,寻找一种方法来解决这个问题,但到目前为止还没有想出多少办法 我的文件夹结构如下: C:\ └───ParentFolder ├───ChildFolder1 │ ├───SubFolderA_1 │ ├───SubFolderA_2 │ ├───SubFolderA_3 │ ├───SubFolderA_4 │ ├───SubFolderB_1 │ ├───SubFolderB_

我的问题可能并不复杂,但我一直在挠头,寻找一种方法来解决这个问题,但到目前为止还没有想出多少办法

我的文件夹结构如下:

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脚本,它可以利用“子文件夹”名称的序列化特性删除旧版本,只保留最新的子文件夹

使用上面的示例,这意味着脚本将删除子文件夹A_1到子文件夹A_3和子文件夹B_1到子文件夹B_3,在子文件夹中只保留子文件夹A_4和子文件夹B_4

有人知道怎么做吗?我在考虑对象排序+递归函数+模式匹配,但我似乎没有取得任何进展。顺便说一句,我是个笨蛋

非常感谢您的帮助。

这里有一种方法。[grin]它的核心是
组对象
cmdlet。有一点经常被忽略,那就是使用计算属性的能力,就像使用
Select-Object
cmdlet一样

# 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
====================

如果只有一个下划线

  • 列出具有多个通配符的文件夹
  • 在下划线处拆分全名,然后
  • 按第一部分分组
  • 迭代组
  • 按降序排序(如果可能存在转移位置,则转换为int或使用$tonnatural)和
  • 跳过第一步
  • 删除剩余文件夹
这与Lee_Dailey的脚本非常相似,但将对所有数字进行排序,并用零填充到一个唯一的宽度

## $ToNatural from Roman Kuzmin source https://stackoverflow.com/a/5429048/6811411
$ToNatural = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20,"0") }) }

Get-ChildItem C:\ParentFolder\ChildFolder*\Subfolder* | 
  Group-Object @{e={$_.fullname.split('_')[0]}} | ForEach-Object {
    $_.Group | Sort $ToNatural -Descending | Select -Skip 1 | Remove-Item -WhatIf
  }

如果输出看起来正常,请删除尾随的
-WhatIf

Nice one(+1)即将发布类似脚本。但是如果尾随计数超过9/1,会发生什么呢?@LotPings-hah!很好的一点。。。我忘了,
排序对象
将在不知道数字的情况下进行字符串排序。[脸红]我要去修了…非常感谢李戴利。我也试过你的脚本,加上“-recurse-force-confirm:$false”,这个脚本非常有效。删除项目。再次感谢。@Dustree-不客气!很高兴能帮上一点忙。。。[咧嘴笑]非常受欢迎的LotPings,这非常有效。我只需要在Remove Item函数中添加“-recurse-force-confirm:$false”,以避开不断出现的提示“处的项有子项且未指定recurse参数。如果继续,所有子项都将与该项一起删除。是否确实要继续?[Y]是[A]对所有项[N]否[L]否对所有项[S]挂起[?]帮助(默认值为“Y”):“您好,很高兴您加入了StackOverflow社区。提问时-请按照下面链接中的说明进行操作,以便我们能够有效地帮助您。请让我们知道你到目前为止尝试了什么,我们将在此基础上帮助你。