脚本接受路径作为参数,然后删除所有空目录需要一些增强

时间:2013-04-24 00:56:54

标签: powershell directory

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

1 个答案:

答案 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)]--
             }
        }