File 如何使用PowerShell删除空的子文件夹?

File 如何使用PowerShell删除空的子文件夹?,file,powershell,recursion,delete-directory,File,Powershell,Recursion,Delete Directory,我有一个股票,是最终用户的“垃圾抽屉”。他们可以根据自己的需要创建文件夹和子文件夹。我需要实现一个脚本来删除创建超过31天的文件 我从Powershell开始。我需要继续执行文件删除脚本,删除现在为空的子文件夹。由于子文件夹的嵌套,我需要避免删除没有文件的子文件夹,但它下面有一个子文件夹,其中包含一个文件 例如: FILE3a已满10天文件3已存在45天 我想清理结构,删除超过30天的文件,并删除空的子文件夹 C:\Junk\subfolder1a\subfolder2a\FILE3a C:

我有一个股票,是最终用户的“垃圾抽屉”。他们可以根据自己的需要创建文件夹和子文件夹。我需要实现一个脚本来删除创建超过31天的文件

我从Powershell开始。我需要继续执行文件删除脚本,删除现在为空的子文件夹。由于子文件夹的嵌套,我需要避免删除没有文件的子文件夹,但它下面有一个子文件夹,其中包含一个文件

例如:

  • FILE3a
    已满10天<代码>文件3已存在45天
  • 我想清理结构,删除超过30天的文件,并删除空的子文件夹
C:\Junk\subfolder1a\subfolder2a\FILE3a
C:\Junk\subfolder1a\subfolder2a\subfolder3a
C:\Junk\subfolder1a\subfolder2B\FILE3b
预期结果:

  • 删除:
    FILE3b
    子文件夹2b
    子文件夹3a
  • 离开:
    子文件夹1A
    子文件夹2A
    文件3A

我可以递归地清理文件。如何在不删除子文件夹1a的情况下清理子文件夹?(垃圾文件夹将始终保留。)

要删除超过30天的文件:

get-childitem -recurse |
    ? {$_.GetType() -match "FileInfo"} |
    ?{ $_.LastWriteTime -lt [datetime]::now.adddays(-30) }  |
    rm -whatif
(只需删除
-whatif
即可实际执行。)

后续行动:

 get-childitem -recurse |
     ? {$_.GetType() -match "DirectoryInfo"} |
     ?{ $_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0 } |
     rm -whatif

我将分两步执行此操作-首先删除旧文件,然后删除空目录:

Get-ChildItem -recurse | Where {!$_.PSIsContainer -and `
$_.LastWriteTime -lt (get-date).AddDays(-31)} | Remove-Item -whatif

Get-ChildItem -recurse | Where {$_.PSIsContainer -and `
@(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -recurse -whatif

这种类型的操作演示PowerShell中嵌套管道的功能,第二组命令演示了这一功能。它使用嵌套管道递归确定任何目录下是否有零个文件。

根据第一个答案的精神,以下是删除空目录的最短方法:

ls -recurse | where {!@(ls -force $_.fullname)} | rm -whatif

当目录包含隐藏文件夹时,需要-force标志,例如.svn

添加到最后一个文件夹:

while (Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Test-Path) {
    Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Remove-Item
}

这将使它在$StartingPoint下继续搜索以删除任何空文件夹时完成。我需要一些企业友好的功能。这是我的照片

我从其他答案的代码开始,然后添加了一个带有原始文件夹列表的JSON文件(包括每个文件夹的文件计数)。删除空目录并记录这些目录


这将在父目录之前对子目录进行排序,以解决空嵌套目录问题

dir -Directory -Recurse |
    %{ $_.FullName} |
    sort -Descending |
    where { !@(ls -force $_) } |
    rm -WhatIf
这对我有用

$limit = (Get-Date).AddDays(-15) 

$path = "C:\Some\Path"
删除早于
$limit
的文件:

Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
删除旧文件后留下的所有空目录:

Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

如果要在类型上进行匹配,可以使用-is运算符,例如$\uis-is[IO.FileInfo]。这些尾随的反勾号是多余的。没有它们的代码运行得很好。是的,它们非常有用。我的希望是,对于PoSh的下一个版本,我们可以免除Where PSIsContainer测试。如果我可以直接从Get-ChildItem请求,例如Get-ChildItem-Recurse-Container或Get-ChildItem-Recurse-Leaf,那就更好了。对于提供者来说,进行这种过滤也是一种非常好的性能优化。人可以做梦。:-)非常感谢。这个解决方案正是我想要的。递归检查子文件夹中是否有剩余的文件是我无法理解的,更不用说语法和嵌套了。我是PowerShell的新手,“@”是什么?“@”语法确保无论我们得到的结果是($null)还是单个结果或结果数组,使用@()的最终可见结果始终是一个包含0、1或N项的数组。这就是我如何确定结果将具有Length属性,并且Length属性用于数组(与字符串相反,如果结果是单个字符串值,则可能会返回字符串)。像这样的动态语言可能非常强大,但它们会让你思考。:-)删除管道实际上包含一个小错误。我在一个文件夹中尝试了它,该文件夹包含由
[]
包围的子文件夹。修复非常简单,
@($| Get ChildItem-Recurse | Where{!$.psicContainer})
(而不是
Get ChildItem$|.FullName-Recurse
)。此管道的一个缺点是它正在收集完整的集合,然后按照我所能说的方式对其进行操作。。因此,在一棵大树中,会有很长的延迟,因为它会扫描所有内容,然后再看到任何删除的内容。这里有一个脚本:这个脚本要复杂得多,但提供了更直接的反馈。它不会删除嵌套的空目录,你有解决方法吗?他的意思是在目录结构
mda\b\c
中,c是空的,b也没有其他文件,这只会删除c。他需要整个空的
\b\c
子树,就像基思的脚本一样。你指的是哪个答案?对答案相对位置的引用不可靠,因为它们取决于视图(投票/最新/活动)和接受答案的变化以及随时间的变化(投票、活动和接受状态)。
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse