在@Shay Levy的帮助下,我有这样一个剧本:
param (
[parameter (mandatory=$true,position=0)]
[string]$Path
)
Get-ChildItem $Path -Recurse -Force |
Where-Object {$_.PSIsContainer -and (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0} | Remove-Item
它的作用是:接受一个路径作为参数 - 递归地找到所有目录 - 如果它是一个空文件夹(下面没有子项目),它将被删除。它工作正常,但我想让它完美。
解释特殊情况的示例:我有一个文件夹作为这样的文件夹结构:folder/subfolder1.1/subfolder2.1/subfolder3.1.
每个子文件夹是其父项下面唯一的子项。我有一个名为“文件夹”的目录,它只包含一个子文件夹“subfolder1.1”,没有文件。 “Subfolder1.1”只包含一个子文件夹“subfolder2.1”而没有文件。 “subfolder2.1”包含“subfolder3.1”,没有文件。运行此脚本后,真正被删除的是“subfolder3.1”,这是有道理的。
这里有一些东西:删除“subfolder3.1”后,其父文件夹“subfolder2.1”变为空文件夹,可以删除。但是由于脚本已经通过了这一点,因此在我再次运行脚本之前无法删除“subfolder2.1”。
完美的脚本将:首先删除“subfolder3.1”,然后检查其父文件夹并找到“哦,它的父子文件夹2.1现在也是空的,让我们删除它父文件夹子文件夹2.1”。删除子文件夹2.1后,检查其父文件并找到“哦,子文件夹1.1现在为空,让我们删除它”。最终,在删除所有子文件夹后,此结构“文件夹”的顶层将被删除,因为它是空的。
我在脚本中添加了“sort -descending”,它似乎对我没有任何作用。
param (
[parameter (mandatory=$true,position=0)]
[string]$Path
)
Get-ChildItem $Path -Recurse -Force |
Where-Object {$_.PSIsContainer -and (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0} |
Sort -descending |Remove-Item
添加“sort”命令的逻辑是:上面的文件夹结构按此顺序传送:
folder
folder/subfolder1.1
folder/subfolder1.1/subfolder2.1
folder/subfolder1.1/subfolder2.1/subfolder3.1
按照上面的顺序,删除“folder / subfolder1.1 / subfolder2.1 / subfolder3.1”后,由于脚本已经通过了点,因此无法删除2.1和1.1和文件夹。所以我在脚本中加入了“sort -descending”,希望这个文件夹结构按此顺序进行管道传输:
folder/subfolder1.1/subfolder2.1/subfolder3.1
folder/subfolder1.1/subfolder2.1
folder/subfolder1.1
folder
我希望首先删除3.1,然后它可以删除2.1,因为2.1在3.1删除后变为空。等等。这个梦想很美,但不起作用。
================================== UPDATE1:
2013年4月25日:@mjolinor感谢您的帮助。我立即运行它并得到这样的错误:
...............
+ Foreach {
+ ~
Missing opening '(' after keyword 'foreach'.
...............
我通过在第一个foreach循环中修改这一行来修复它:
...............
Foreach ($dir in $dirs) {
...............
现在上述错误消失了,又向前迈了一步。当我可以运行它时,我可以看到它是迭代文件夹但最终出现了另一个错误:
...............
Index operation failed; the array index evaluated to null.
At C:\Documents\ManualScripts\Cleanup-no-file-and-subdir-dir-rev02.ps1:11 char:13
+ $dirs[$_] = (Get-ChildItem $_ -Force | Measure-Object).Count
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
...............
继续努力并与您分享。
============================= UPDATE2:
2013年4月25日
上述错误的原因是这一行: ...........
Foreach ($dir in $dirs) {
...........
将其更改为: ...........
Foreach ($dir in $_) {
...........
错误消失了。我可以看到dirs列表向下滚动控制台。但似乎“排序”没有像我预期的那样工作,因为测试文件夹仍然显示“升序”顺序。摘录如下:
...........
H:\archive\folder\Sub1
H:\archive\folder\Sub1\Sub2.1
H:\archive\folder\Sub1\Sub2.1\Sub3.1
...........
“folder \ Sub1 \ Sub2.1 \ Sub3.1”是我创建的测试文件夹结构。
=================================== 更新3
2013年4月26日。
现在有效!
.........................................
param (
[parameter (mandatory = $True, position = 0)]
[string]$Path
)
$dirs = @{}
Get-ChildItem $Path -Recurse -Force |
Where-Object {$_.PSIsContainer} |
Select -ExpandProperty FullName |
Foreach {
$dirs[$_] = (Get-ChildItem $_ -Force | Measure-Object).Count
}
$dirs.keys | Sort Length -Descending # This line is only for displaying output to mornitor sorting is all right
$dirs.keys | Sort Length -Descending |
Foreach {
If ($dirs[$_] -eq 0)
{
Remove-item $_
$dirs[($_ | Split-Path -Parent)]--
}
}
...................................
谢谢@mjolinor。我喜欢哈希表:)
答案 0 :(得分:1)
未经测试,但我认为这应该有效:
param (
[parameter (mandatory=$true,position=0)]
[string]$Path
)
$dirs = @{}
Get-ChildItem $Path -Recurse -Force |
Where-Object {$_.PSIsContainer} |
select -ExpandProperty FullName
foreach {
$dirs[$_] = (Get-ChildItem $_ -Force | Measure-Object).Count
}
$dirs.keys | Sort length -descending |
foreach {
if ($dirs[$_] -eq 0)
{
Remove-Item $_
$dirs[($_ | Split-Path -Parent)]--
}
}