我需要从zipfile解压缩一个特定的目录.
例如,从zipfile'c:\ tmp\test.zip'中提取目录'test\etc\script',并将其放在c:\ tmp\output\test\etc\script中.
下面的代码有效,但有两个怪癖:
我需要递归地找到zip文件(函数finditem)中的目录('script'),虽然我已经知道了路径('c:\ tmp\test.zip\test\etc\script')
使用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)
Run Code Online (Sandbox Code Playgroud)
Ans*_*ers 10
我不知道最优雅,但安装了.Net 4.5,你可以使用命名空间中的ZipFile类System.IO.Compression:
[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)
}
Run Code Online (Sandbox Code Playgroud)
的3 次的参数ExtractToFile()可以省略.如果存在,它定义是否覆盖现有文件.
至于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)
Run Code Online (Sandbox Code Playgroud)
Windows PowerShell 5.0(包含在Windows 10中)本身支持使用Expand-Archivecmdlet 提取ZIP文件:
Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19935 次 |
| 最近记录: |