0

在@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现在也是空的,让我们删除它父文件夹subfolder2.1”。删除 subfolder2.1 后,检查其父文件夹,发现“哦,subfolder1.1 现在为空,我们删除它”。最终,在删除所有子文件夹后,该结构“文件夹”的顶层将被删除,因为它是空的。

我在脚本中添加了一个“排序降序”,它似乎对我没有任何作用。

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

添加“排序”命令的逻辑是:上述文件夹结构按以下顺序管道:

folder
folder/subfolder1.1
folder/subfolder1.1/subfolder2.1
folder/subfolder1.1/subfolder2.1/subfolder3.1

按上述顺序,删除“文件夹/子文件夹1.1/子文件夹2.1/子文件夹3.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,因为在删除 3.1 后 2.1 变为空。等等。这个梦想很美好,但行不通。

===================================更新1:

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

…………………………………………………………………………

正在研究它,并将与您分享。

==============================更新2:

2013 年 4 月 25 日

上述错误的原因是这一行:......

Foreach ($dir in $dirs) {

............

改成:......

Foreach ($dir in $_) {

............

错误消失了。我可以看到向下滚动控制台的目录列表。但似乎“排序”没有像我预期的那样工作,因为测试文件夹仍然显示“升序”顺序。摘录如下:

............

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。我喜欢哈希表:)

4

1 回答 1

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)]--
             }
        }
于 2013-04-24T01:33:32.173 回答