我的问题可能\可能不会很复杂,但是我一直在抓挠头,寻找解决方法,但是到目前为止并没有提出太多建议。
我的文件夹结构如下:
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脚本,该脚本将利用“ SubFolders”名称的序列化性质来删除较旧的版本,而仅保留最新的SubFolders。
使用上面的示例,这意味着脚本会将SubFolderA_1删除为SubFolderA_3,将SubFolderB_1删除为SubFolderB_3,仅在ChildFolders中保留SubFolderA_4和SubfolderB_4。
有人会知道这样做的方法吗?我当时在考虑对象排序+递归函数+模式匹配,但是我似乎一无所获。顺便说一下,我是PS菜鸟。
非常感谢您的帮助。
答案 0 :(得分:1)
这是一种方法。 [咧嘴]的心脏是Group-Object
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
====================
答案 1 :(得分:0)
只要只有一个下划线,
这与Lee_Daileys脚本非常相似,但是将对所有数字进行排序,并在所有数字的前面用零填充到唯一宽度。
## $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