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

使用PowerShell批量压缩子文件夹HEIC文件并删除原文件的问题及解决方案

批量处理子目录HEIC文件压缩需求

需要对多层子文件夹中的HEIC格式照片执行批量压缩、按目录名规则命名压缩包、压缩成功后删除原HEIC文件的操作。

原始目录结构示例

Years
├─2019
│  └─09.01.19 - Visiting the Zoo
│          Photo1.HEIC
│          Photo1.JPG
│          Photo2.HEIC
│          Photo2.JPG
│          Photo3.HEIC
│          Photo3.JPG
├─2020
│  └─09.02.20 - Pumpkin Picking
│          DSC01.HEIC
│          DSC01.JPG
│          DSC02.HEIC
│          DSC02.JPG
│          DSC03.HEIC
│          DSC03.JPG
└─2021
   └─09.04.21 - Whitewater Rafting
          IMG01.HEIC
          IMG01.JPG
          IMG02.HEIC
          IMG02.JPG
          IMG03.HEIC
          IMG03.JPG

预期处理后目录结构

Years
├─2019
│  └─09.01.19 - Visiting the Zoo
│          Photo1.JPG
│          Photo2.JPG
│          Photo3.JPG
│          09.01.19 - Visiting the Zoo(HEIC).7z
├─2020
│  └─09.02.20 - Pumpkin Picking
│          DSC01.JPG
│          DSC02.JPG
│          DSC03.JPG
│          09.02.20 - Pumpkin Picking(HEIC).7z
└─2021
   └─09.04.21 - Whitewater Rafting
          IMG01.JPG
          IMG02.JPG
          IMG03.JPG
          09.04.21 - Whitewater Rafting(HEIC).7z
初始脚本及存在问题

最初编写的PowerShell脚本如下:

$7zipPath = "$env:ProgramFiles\7-Zip\7z.exe"
if (-not (Test-Path -Path $7zipPath -PathType Leaf)) {
    throw "7 zip 文件 '$7zipPath' 未找到"
}
Set-Alias 7zip $7zipPath
$path = "T:\TEST\YEARS"
$dest = "T:\TEST\YEARS"
$mask = "*.HEIC"
$files = dir $path -Recurse -Include $mask 
ForEach ($file in $files) 
    {
     7zip a tzip mx "$dest\$($file.basename)HEIC.7z" $file

    }
Get-ChildItem -Path 'T:\TEST\YEARS' $mask -Recurse | foreach { Remove-Item -Path $_.FullName }

存在的问题如下:

  • 压缩包全部输出到T:\TEST\YEARS根目录,没有存入对应HEIC文件所在的子文件夹
  • 不同子文件夹的HEIC文件被合并到同一个压缩包,不符合按目录独立打包的要求
  • 压缩逻辑异常,尚未验证删除逻辑的可用性
修复后的可用脚本

系统自带Zip格式版本(无需额外安装软件)

# 修改此处为你的Years文件夹实际路径
$yearDir = "$PSScriptRoot\YEARS" 

try {
    $yearDirResults = Get-ChildItem -Path $yearDir -Directory -ErrorAction Stop
}
catch {
    Write-Error $Error[0] -ErrorAction Stop
}

# 遍历所有年份文件夹
foreach ($year in $yearDirResults) {
    $compressError = $false 
    try {
        # 遍历年份文件夹下的所有活动子文件夹
        Get-ChildItem -Path $year.FullName -Directory -ErrorAction Stop | ForEach-Object {
            # 检查当前子文件夹是否存在HEIC文件
            $heicFiles = Test-Path "$($_.FullName)\*" -Include '*.heic' 
            if ($heicFiles) {
                $compressionPath = "$($_.FullName)\*.HEIC" 
                # 生成压缩包名称:子文件夹名+(HEIC)
                $zipName = "$(Split-Path $($_.FullName) -Leaf)(HEIC).zip" 
                # 压缩包输出路径为当前子文件夹路径
                $heicZipOutput = Join-Path -Path $($_.FullName) -ChildPath $zipName 
                Write-Host "正在压缩 $compressionPath ,输出到 $heicZipOutput"
                try {
                    # 压缩成功后才执行删除,使用Update参数:已有压缩包则增量更新,不会直接覆盖
                    Compress-Archive -Path $compressionPath -DestinationPath $heicZipOutput -Update -CompressionLevel Fastest -ErrorAction Stop 
                    # 测试阶段可取消下一行注释,仅预览操作不实际执行
                    # -WhatIf
                }
                catch {
                    $compressError = $true
                    Write-Error $Error[0]
                }

                if($compressError){
                    Write-Warning "创建压缩包 $heicZipOutput 出错,不会删除任何文件"
                } else {
                    Write-Warning "正在删除 $($_.FullName) 下的HEIC文件"
                    try {
                        Remove-Item -Path "$($_.FullName)\*" -Include '*.heic' -ErrorAction Stop -Force
                        # 测试阶段可取消下一行注释,仅预览删除操作不实际执行
                        # -WhatIf
                    }
                    catch {
                        Write-Error $Error[0] -ErrorAction Continue
                    }
                }
                
            }
            else {
                Write-Warning "当前文件夹 $($_.FullName) 未找到HEIC文件,跳过压缩"
            }    
        }
    }
    catch {
        Write-Error $Error[0] -ErrorAction Stop
    }
}

7z格式版本(需提前安装7-Zip)

如果需要输出7z格式,在脚本开头添加7-Zip路径配置:

$7zipPath = "$env:ProgramFiles\7-Zip\7z.exe"
if (-not (Test-Path -Path $7zipPath -PathType Leaf)) {
    throw "7 zip 文件 '$7zipPath' 未找到"
}
Set-Alias 7zip $7zipPath

将脚本中Compress-Archive相关代码替换为以下内容即可:

$heicZipOutput = $heicZipOutput.Replace(".zip",".7z")
7zip a -mx=9 $heicZipOutput $compressionPath

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:54:03