You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell按条件删除文件后递归删除非排除空文件夹实现

PowerShell 删除过期文件后递归清理非排除列表内空文件夹方案

问题背景

现有目录结构如下:

projects
└───folder1
│   │   file001.txt
│   │   file002.txt
│   │   ...
│   │
│   └───subfolder1
│       │   file001.txt
│       │   file002.txt
│       │   ...
│   
└───folder2
│   │   file001.txt
│   │   file002.txt
│   │   ...
│   └───subfolder1
│       │   file001.txt
│       │   file002.txt
│       │   ...
│......................

当前已有PowerShell脚本仅能删除符合过期规则的文件,无法在删完文件后递归删除不在排除列表内的空文件夹,现有脚本代码:

param(
[string] $dir = "C:\projects",
[string] $logfile = "C:\logs\projects.log", 
[string] $days = "30")

$error.clear()
try
{
    # 取指定天数前的零点时间作为过期判断基准
    $refDate = (Get-Date).AddDays(-$days).Date

    # 需要排除、不做处理的文件夹名列表
    $excludeFolders = 'folder1', 'folder4', 'folder8'

    # 拼接排除文件夹的正则匹配规则,每个文件夹名做正则转义后用|分隔
    $notThese = ($excludeFolders | ForEach-Object { [Regex]::Escape($_) }) -join '|'

    Get-ChildItem -Path $dir -Recurse -File | 
    Where-Object { $_.FullName -notmatch $notThese -and $_.LastWriteTime -lt $refDate } | 
    Remove-Item -Force -Verbose 4>$logfile

}

catch {
    Write-Error  $_
}

if (!$error) {
    Write-Host  'Data deleted for files which are older than' $days 'Days'
}

预期执行完成后,排除列表内的文件夹会完整保留,其余路径下的过期文件被删除、空文件夹被递归清理,最终目录结构参考:

projects
└───folder1
│   │   file001.txt
│   │   file002.txt
│   │   ...
│   │
│   └───subfolder1
│       │   file001.txt
│       │   file002.txt
│       │   ...
│   
└───folder2
│......................

实现方案

在原有文件删除逻辑后追加空文件夹清理逻辑即可,注意要从最深层子目录开始向上遍历判断,避免漏删上层空目录:

  1. 遍历目录时按目录深度倒序排列,优先处理深层子文件夹
  2. 跳过路径匹配排除规则的文件夹
  3. 检查当前文件夹下是否存在任何文件/子文件夹,为空则执行删除
  4. 删除操作的日志统一写入指定日志文件

修改后的完整脚本如下:

param(
[string] $dir = "C:\projects",
[string] $logfile = "C:\logs\projects.log", 
[string] $days = "30")

$error.clear()
try
{
    # 取指定天数前的零点时间作为过期判断基准
    $refDate = (Get-Date).AddDays(-$days).Date

    # 需要排除、不做处理的文件夹名列表
    $excludeFolders = 'folder1', 'folder4', 'folder8'

    # 拼接排除文件夹的正则匹配规则,每个文件夹名做正则转义后用|分隔
    $notThese = ($excludeFolders | ForEach-Object { [Regex]::Escape($_) }) -join '|'

    # 第一步:删除符合过期规则的文件
    Get-ChildItem -Path $dir -Recurse -File | 
    Where-Object { $_.FullName -notmatch $notThese -and $_.LastWriteTime -lt $refDate } | 
    Remove-Item -Force -Verbose 4>>$logfile

    # 第二步:递归清理非排除列表内的空文件夹,按深度倒序优先处理深层目录
    Get-ChildItem -Path $dir -Recurse -Directory | 
    Where-Object { $_.FullName -notmatch $notThese } |
    Sort-Object { $_.FullName.Split('\').Count } -Descending |
    Where-Object { -not (Get-ChildItem -Path $_.FullName -Force | Select-Object -First 1) } |
    Remove-Item -Force -Verbose 4>>$logfile

}

catch {
    Write-Error  $_
}

if (!$error) {
    Write-Host  "过期文件(超过$days天未修改)及空文件夹清理完成"
}

关键逻辑说明

  • 日志写入改用>>追加模式,避免第二步清理空文件夹的日志覆盖第一步删文件的日志
  • 空目录判断用Get-ChildItem -Force搭配Select-Object -First 1,遇到第一个子项就停止遍历,比统计全量子项数量的执行效率更高,适合大目录场景
  • 排序时按路径分割后的层级数倒序,保证从最深层目录开始判断删除,不会出现子目录没删导致上层目录被误判为非空的问题
  • 排除规则复用原有正则逻辑,和文件删除阶段的排除范围完全一致,不会误删排除列表内的空目录

内容的提问来源于stack exchange,提问作者Mendizalea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 08:18:17