使用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
相关产品推荐
相关产品推荐

