使用 7zip 压缩 powershell 5.0

问题描述

我已经自定义一个 powershell 代码,将超过 7 天的文件从源文件夹压缩到子文件夹,然后在压缩完成后从源中删除原始文件。该代码文件量较少的内置 Compress-Archive 和 Remove-Item cmdlet 中运行良好,但对于大量文件需要更多时间和系统内存。所以,我正在研究使用 7zip 的解决方案,因为它更快。

下面的脚本可以正确压缩,但不遵循仅超过 7 天的文件的条件,并从源文件夹中删除所有文件。它应该只压缩和删除超过 7 天的文件

我尝试了所有可能的方法来排除故障,但没有成功。有人可以提出可能的解决方案吗?

if (-not (test-path "$env:ProgramFiles\7-Zip\7z.exe")) {throw "$env:ProgramFiles\7-Zip\7z.exe needed"} 
set-alias sz "$env:ProgramFiles\7-Zip\7z.exe" 

$Date = Get-Date -format yyyy-MM-dd_HH-mm 
$Source = "C:\Users\529817\New folder1\New folder_2\" 
$Target = "C:\Users\529817\New folder1\New folder_2\ARCHIVE\"
Get-ChildItem -path $Source | sz a -mx=9 -sdel $Target\$Date.7z $Source

解决方法

这里有几个问题。第一个是 7-Zip 不接受文件列表作为管道,此外,即使它确实如此,您的 GCI 也会选择每个文件而不是按日期选择。它之所以有效,是因为您将源文件夹作为参数传递给 7-Zip。

7-Zip 接受要压缩的文件列表作为命令行参数:

Usage: 7z <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]

并且您可以通过LastWriteTime过滤GCI的输出来选择您想要的文件。

试着把你的最后一行改成这个

sz a -mx=9 -sdel $Target\$Date.7z (gci -Path $Source |? LastWriteTime -lt (Get-Date).AddDays(-7) | select -expandproperty FullName)

如果您有数百个文件和长路径,那么您可能会遇到命令行长度问题,在这种情况下,您可以改为这样做:

gci -Path $Source |? LastWriteTime -lt (Get-Date).AddDays(-7) |% { sz a -mx=9 -sdel $Target\$Date.7z $_.FullName }

考虑一个包含需要压缩的文件列表的临时文件:-

$tmp = "$($(New-Guid).guid).tmp"
set-content $tmp (gci -Path $Source |? LastWriteTime -lt (Get-Date).AddDays(-7)).FullName
sz a -mmt=8 out.7z @$tmp
Remove-Item $tmp

还要查看 7-Zip 的参数:-mx=9 将是最慢的,因为可能会获得较小的尺寸增益。也许不考虑该参数并采用默认值并考虑添加 -mmt=8 以使用多个线程。