PowerShell调用7-Zip压缩文件夹时,如何仅保留最新PDF文件?
问题分析与解决:7-Zip压缩时排除指定PDF文件
问题背景
需要通过PowerShell调用7-Zip压缩目标文件夹,要求仅保留pdfs子目录中最新的PDF文件,其余旧PDF排除在压缩包外,但现有代码无法实现该效果。
错误原因
- 参数逻辑冲突:代码中同时使用了
-x!*\*.pdf(全局排除所有PDF)和-x@ExcludeFiles.txt(排除列表内文件),叠加后会直接排除所有PDF,包括需要保留的最新文件,完全违背需求。 - 排除列表路径格式错误:
- 仅输出文件名时,7-Zip无法定位到
pdfs子目录下的文件; - 输出绝对路径时,与7-Zip基于压缩根目录的相对路径解析逻辑不匹配,导致无法正确匹配文件。
- 仅输出文件名时,7-Zip无法定位到
修正方案
- 删除
-x!*\*.pdf参数,避免全局排除所有PDF; - 生成排除列表时,输出相对于压缩根目录($ThisFolder)的相对路径(格式为
pdfs\文件名.pdf),确保7-Zip能精准匹配要排除的旧PDF; - 调整文件筛选逻辑,确保正确选中除最新文件外的所有旧PDF。
关键修正代码
生成正确的排除列表
# 获取pdfs目录下除最新PDF外的所有文件,输出相对路径到排除列表 Get-ChildItem "$PDFFolder" -File | Sort-Object CreationTime | Select-Object -SkipLast 1 | ForEach-Object { # 生成相对于$ThisFolder的路径 Join-Path -Path "pdfs" -ChildPath $_.Name } | Out-File "$ExcludeFilelist" -Encoding ascii
调整7-Zip参数数组
移除全局排除PDF的参数,仅保留排除zip和排除列表的参数:
$excludingzips = "-xr!*.zip" $excludingpdflist = "-x@$ExcludeFilelist" [Array]$zipArgs = "a", "-tzip", "$ziptarget", "$ThisFolder", $excludingzips, $excludingpdflist
完整修正代码
$Date = Get-Date -Format "yyyy-MM-dd" $ThisFolder = Get-Location $ziptargetFolder = Split-Path -Parent $ThisFolder $folder = Get-Item $ThisFolder $folderName = $folder.Name $PDFFolder = Join-Path -Path $ThisFolder -ChildPath "pdfs" $ziptarget = Join-Path -Path $ziptargetFolder -ChildPath "$Date`_$folderName.zip" $ExcludeFilelist = Join-Path -Path $ziptargetFolder -ChildPath "ExcludeFiles.txt" # 生成排除列表:pdfs目录下除最新PDF外的所有文件的相对路径 Get-ChildItem "$PDFFolder" -File | Sort-Object CreationTime | Select-Object -SkipLast 1 | ForEach-Object { Join-Path -Path "pdfs" -ChildPath $_.Name } | Out-File "$ExcludeFilelist" -Encoding ascii $zipExePath = "C:\Program Files\7-Zip\7z.exe" $excludingzips = "-xr!*.zip" $excludingpdflist = "-x@$ExcludeFilelist" [Array]$zipArgs = "a", "-tzip", "$ziptarget", "$ThisFolder", $excludingzips, $excludingpdflist & $zipExePath $zipArgs
补充说明
- 使用
Join-Path替代字符串拼接,避免路径分隔符的潜在问题; - 添加
-File参数到Get-ChildItem,确保只处理文件而非目录; - 简化参数拼接方式,提升代码可读性。
内容的提问来源于stack exchange,提问作者Georg
相关产品推荐
相关产品推荐

