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)和
- 跳过第一步
- 删除剩余文件夹
## $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社区。提问时-请按照下面链接中的说明进行操作,以便我们能够有效地帮助您。请让我们知道你到目前为止尝试了什么,我们将在此基础上帮助你。