使用 7zip 压缩 powershell 5.0

Posted

技术标签:

【中文标题】使用 7zip 压缩 powershell 5.0【英文标题】:using 7zip to zip in powershell 5.0 【发布时间】:2021-01-26 20:43:31 【问题描述】:

我已经自定义了一个 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

【问题讨论】:

【参考方案1】:

这里有几个问题。首先是 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 以使用多个线程。

【讨论】:

我试过这个。遗憾的是,这是一个非常缓慢的过程。即使 100 个文件也需要更长的时间。我正在寻找更快的方法,因为我的文件夹每周有 8000 多个文件进行归档。 我已经更新了我的答案,包括一种可能更快的方法来处理很长的文件列表以及对 7-Zip 命令行的优化。 非常感谢。这种方法效果很好。

以上是关于使用 7zip 压缩 powershell 5.0的主要内容,如果未能解决你的问题,请参考以下文章

7zip 正在压缩源路径/空变量

Powershell解压缩功能 - 奇怪的行为

使用 powershell 和 7zip 创建存档的脚本

Powershell - 展开存档并重命名文件,因为它包含无效字符

powershell 7zip的

使用7zip压解各种文件的经常使用命令