我需要从zipfile解压缩特定目录。
例如,提取目录' test \ etc \ script'来自zipfile' c:\ tmp \ test.zip'并将其放在c:\ tmp \ output \ test \ etc \ script。
以下代码有效但有两个怪癖:
我需要递归地找到zip文件(函数finditem)中的目录(' script'),尽管我已经知道了路径(' c:\ tmp \ test.zip \测试\等\脚本&#39)
使用CopyHere我需要确定目标目录,特别是' test \ etc'部分手动
有更好的解决方案吗?感谢。
代码:
function finditem($items, $itemname)
{
foreach($item In $items)
{
if ($item.GetFolder -ne $Null)
{
finditem $item.GetFolder.items() $itemname
}
if ($item.name -Like $itemname)
{
return $item
}
}
}
$source = 'c:\tmp\test.zip'
$target = 'c:\tmp\output'
$shell = new-object -com shell.application
# find script folder e.g. c:\tmp\test.zip\test\etc\script
$item = finditem $shell.NameSpace($source).Items() "script"
# output folder is c:\tmp\output\test\etc
$targetfolder = Join-Path $target ((split-path $item.path -Parent) -replace '^.*zip')
New-Item $targetfolder -ItemType directory -ErrorAction Ignore
# unzip c:\tmp\test.zip\test\etc\script to c:\tmp\output\test\etc
$shell.NameSpace($targetfolder).CopyHere($item)
答案 0 :(得分:10)
我不知道最优雅,但安装了.Net 4.5,您可以使用System.IO.Compression
命名空间中的ZipFile
类:
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null
$zipfile = 'C:\path\to\your.zip'
$folder = 'folder\inside\zipfile'
$dst = 'C:\output\folder'
[IO.Compression.ZipFile]::OpenRead($zipfile).Entries | ? {
$_.FullName -like "$($folder -replace '\\','/')/*"
} | % {
$file = Join-Path $dst $_.FullName
$parent = Split-Path -Parent $file
if (-not (Test-Path -LiteralPath $parent)) {
New-Item -Path $parent -Type Directory | Out-Null
}
[IO.Compression.ZipFileExtensions]::ExtractToFile($_, $file, $true)
}
ExtractToFile()
的3 rd 参数可以省略。如果存在,它定义是否覆盖现有文件。
答案 1 :(得分:7)
只要知道zip中的文件夹位置,就可以简化原始代码:
$source = 'c:\tmp\test.zip' # zip file
$target = 'c:\tmp\output' # target root
$folder = 'test\etc\script' # path in the zip
$shell = New-Object -ComObject Shell.Application
# find script folder e.g. c:\tmp\test.zip\test\etc\script
$item = $shell.NameSpace("$source\$folder")
# actual destination directory
$path = Split-Path (Join-Path $target $folder)
if (!(Test-Path $path)) {$null = mkdir $path}
# unzip c:\tmp\test.zip\test\etc\script to c:\tmp\output\test\etc\script
$shell.NameSpace($path).CopyHere($item)
答案 2 :(得分:6)
Windows PowerShell 5.0(包含在Windows 10中)本身支持使用Expand-Archive
cmdlet提取ZIP文件:
Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference