问题描述
我已经自定义了一个 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
以使用多个线程。