提问人:Brian 提问时间:6/17/2023 最后编辑:mklement0Brian 更新时间:6/18/2023 访问量:61
PowerShell:以迭代方式从文件夹子树中删除所有空子文件夹
PowerShell: Iteratively remove all empty subfolders from a folder subtree
问:
我编写了以下脚本来递归删除任何空文件夹。我已经在沙盒中对此进行了测试,它似乎是安全的。也就是说,它只会删除一个为空的文件夹,并且它只会在起始父文件夹内的子文件夹中导航,并且不会无意中在目录中进一步向上移动。
所以,如果你能快速看一下我的剧本,并告诉我你是否看到任何危险,我将不胜感激。谢谢!
$isEmpty=1
$iteration=0
while ($isEmpty) {
$isEmpty=0
$iteration++
get-childitem -Directory -Force -recurse | ForEach-Object {
$count=(Get-ChildItem -Path $_.FullName -Force).count
if ($count -eq 0) {
$isEmpty=1
Write-Host "$iteration`t$count`t$_"
$path="\\?\"+$_.FullName
$folder= Get-item -Path $path
$folder.Attributes = $folder.Attributes -band -bnot [System.IO.FileAttributes]::ReadOnly
$folder.Attributes = $folder.Attributes -band -bnot [System.IO.FileAttributes]::Hidden
Remove-Item -Force -LiteralPath $path
}
}
}
答:
$isEmpty=1
,$isEmpty=0
虽然 和 确实作为隐式布尔值工作,但最好显式使用布尔值,即 和:1
0
$true
$false
$isEmpty = $true
$isEmpty = $false
Get-ChildItem -Path $_.FullName
如果您知道路径是文本(逐字)路径而不是通配符表达式,请使用 代替 .-LiteralPath
-Path
Get-Item -Path $path
该建议同样适用,但更重要的是:-LiteralPath
- 也许令人惊讶的是 - 请参阅 GitHub 问题 #6502 - 即使通过显式文本路径定位文件系统项 - 也需要使用 Get-Item 或
Get-ChildItem
来定位隐藏项。-Force
$folder.Attributes = $folder.Attributes -band -bnot [System.IO.FileAttributes]::ReadOnly
[...]
您无需显式清除文件系统项中的 and 属性即可让 Remove-Item
删除它们 - 使用 就足够了。Hidden
ReadOnly
-Force
退后一步:
如果自下而上处理目录(文件夹),即从目录子树中的叶目录开始,然后迭代向上遍历,则可以避免文件夹子树的多次遍历:
Get-ChildItem -Directory -Force -Recurse |
Sort-Object -Descending { ($_.FullName -split '[\\/]').Count } |
Where-Object {
if (-not ($_ | Get-ChildItem -Force | Select-Object -First 1)) {
$_ | Remove-Object -Force -WhatIf
}
}
注意:
上述命令中的
-WhatIf
通用参数可预览操作。一旦确定操作将执行所需的操作,请删除并重新执行。-WhatIf
也就是说,考虑到任务的迭代性质,只会显示将被删除的空叶目录,而不会显示因删除任何叶子而也会被删除的任何祖先。
-WhatIf
- 只有实际运行命令(通过删除)才会告诉您实际结果。
-WhatIf
- 因此,最好在调整代码时保留整个目录子树的备份。
- 只有实际运行命令(通过删除)才会告诉您实际结果。
评论
Remove-Item -Force -LiteralPath $path -WhatIf
-whatif