从zip存档中提取一个文件

发布于 2025-01-28 17:13:47 字数 352 浏览 5 评论 0 原文

我正在使用下一个代码下载一些zip存档:

$client = new-object System.Net.WebClient
$client.DownloadFile("https://chromedriver.storage.googleapis.com/$LatestChromeRelease/chromedriver_win32.zip","D:\MyFolder.zip")

结果,我得到包含必需文件的zip存档“ myfolder.zip”(让您想象'test.txt')。

如何从zip存档中将此特定文件提取到给定文件夹中?

I'm using the next code to download some zip archive:

$client = new-object System.Net.WebClient
$client.DownloadFile("https://chromedriver.storage.googleapis.com/$LatestChromeRelease/chromedriver_win32.zip","D:\MyFolder.zip")

As the result I get the ZIP archive "MyFolder.zip" that contains a required file (lets imagine 'test.txt').

How I can extract this particular file from the ZIP archive into a given folder?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天邊彩虹 2025-02-04 17:13:47

PowerShell 4+具有 命令,但截至PS 7.2.3,它只能完全提取存档。因此,将其提取到临时目录并复制您感兴趣的文件。

如果您有PS 5.1+可用,请向下滚动以获取使用.NET类的更有效的解决方案。

$archivePath = 'D:\MyFolder.zip'
$destinationDir = 'D:\MyFolder'

# Relative path of file in ZIP to extract. 
$fileToExtract = 'test.txt'

# Create destination dir if not exist.
$null = New-Item $destinationDir -ItemType Directory -Force

# Create a unique temporary directory
$tempDir = Join-Path ([IO.Path]::GetTempPath()) ([System.Guid]::NewGuid().ToString('n'))
$null = New-Item $tempDir -ItemType Directory

try {
    # Extract archive to temp dir
    Expand-Archive -LiteralPath $archivePath -DestinationPath $tempDir

    # Copy the file we are interested in
    $tempFilePath = Join-Path $tempDir $fileToExtract
    Copy-Item $tempFilePath $destinationDir 
}
finally {
    # Remove the temp dir
    if( Test-Path $tempDir ) { 
        Remove-Item $tempDir -Recurse -Force -EA Continue 
    }
}

使用 ps 5.1+您可以使用。净类直接提取单个文件(不必提取整个存档):

# Load required .NET assemblies. Not necessary on PS Core 7+.
Add-Type -Assembly System.IO.Compression.FileSystem

$archivePath = 'D:\MyFolder.zip'
$destinationDir = 'D:\MyFolder'

# Relative path of file in ZIP to extract.
# Use FORWARD slashes as directory separator, e. g. 'subdir/test.txt'
$fileToExtract = 'test.txt'

# Create destination dir if not exist.
$null = New-Item $destinationDir -ItemType Directory -Force

# Convert (possibly relative) paths for safe use with .NET APIs
$resolvedArchivePath    = Convert-Path -LiteralPath $archivePath
$resolvedDestinationDir = Convert-Path -LiteralPath $destinationDir

$archive = [IO.Compression.ZipFile]::OpenRead( $resolvedArchivePath )
try {
    # Locate the desired file in the ZIP archive.
    # Replace $_.Fullname by $_.Name if file shall be found in any sub directory.
    if( $foundFile = $archive.Entries.Where({ $_.FullName -eq $fileToExtract }, 'First') ) {
    
        # Combine destination dir path and name of file in ZIP
        $destinationFile = Join-Path $resolvedDestinationDir $foundFile.Name
        
        # Extract the file.
        [IO.Compression.ZipFileExtensions]::ExtractToFile( $foundFile[ 0 ], $destinationFile )
    }
    else {
        Write-Error "File not found in ZIP: $fileToExtract"
    }
}
finally {
    # Dispose the archive so the file will be unlocked again.
    if( $archive ) {
        $archive.Dispose()
    }
}

注释:

  • convert-path 应该当将可能是相对路径的powershell路径传递到.NET API时。 .NET框架有其自己的当前目录,这不一定与PowerShell的目录相匹配。使用转换path 我们转换为绝对路径,因此.NET的当前目录不再相关。
  • where .foreach 是powershell 固有方法所有对象都可用。它们类似于 where-object foreach-object 命令,但更有效。将'first'作为第二个参数传递给在我们找到文件后立即停止搜索。
  • 请注意,即使只有一个元素匹配, where 始终输出a 集合。这与 where-object 返回A 单个对象(如果只有单个元素匹配)。因此,我们必须编写 $ undfile [0] 将其传递给函数 extracttofile ,而不是 $ undfile ,这将是一个数组。

PowerShell 4+ has an Expand-Archive command but as of PS 7.2.3 it can only extract the archive completely. So extract it to a temporary directory and copy the file you are interested in.

If you have PS 5.1+ available, scroll down for a more efficient solution that uses .NET classes.

$archivePath = 'D:\MyFolder.zip'
$destinationDir = 'D:\MyFolder'

# Relative path of file in ZIP to extract. 
$fileToExtract = 'test.txt'

# Create destination dir if not exist.
$null = New-Item $destinationDir -ItemType Directory -Force

# Create a unique temporary directory
$tempDir = Join-Path ([IO.Path]::GetTempPath()) ([System.Guid]::NewGuid().ToString('n'))
$null = New-Item $tempDir -ItemType Directory

try {
    # Extract archive to temp dir
    Expand-Archive -LiteralPath $archivePath -DestinationPath $tempDir

    # Copy the file we are interested in
    $tempFilePath = Join-Path $tempDir $fileToExtract
    Copy-Item $tempFilePath $destinationDir 
}
finally {
    # Remove the temp dir
    if( Test-Path $tempDir ) { 
        Remove-Item $tempDir -Recurse -Force -EA Continue 
    }
}

With PS 5.1+ you can use .NET classes to directly extract a single file (without having to extract the whole archive):

# Load required .NET assemblies. Not necessary on PS Core 7+.
Add-Type -Assembly System.IO.Compression.FileSystem

$archivePath = 'D:\MyFolder.zip'
$destinationDir = 'D:\MyFolder'

# Relative path of file in ZIP to extract.
# Use FORWARD slashes as directory separator, e. g. 'subdir/test.txt'
$fileToExtract = 'test.txt'

# Create destination dir if not exist.
$null = New-Item $destinationDir -ItemType Directory -Force

# Convert (possibly relative) paths for safe use with .NET APIs
$resolvedArchivePath    = Convert-Path -LiteralPath $archivePath
$resolvedDestinationDir = Convert-Path -LiteralPath $destinationDir

$archive = [IO.Compression.ZipFile]::OpenRead( $resolvedArchivePath )
try {
    # Locate the desired file in the ZIP archive.
    # Replace $_.Fullname by $_.Name if file shall be found in any sub directory.
    if( $foundFile = $archive.Entries.Where({ $_.FullName -eq $fileToExtract }, 'First') ) {
    
        # Combine destination dir path and name of file in ZIP
        $destinationFile = Join-Path $resolvedDestinationDir $foundFile.Name
        
        # Extract the file.
        [IO.Compression.ZipFileExtensions]::ExtractToFile( $foundFile[ 0 ], $destinationFile )
    }
    else {
        Write-Error "File not found in ZIP: $fileToExtract"
    }
}
finally {
    # Dispose the archive so the file will be unlocked again.
    if( $archive ) {
        $archive.Dispose()
    }
}

Notes:

  • Convert-Path should be used when passing PowerShell paths that might be relative paths, to .NET APIs. The .NET framework has its own current directory, which doesn't necessarily match PowerShell's. Using Convert-Path we convert to absolute paths so the current directory of .NET is no longer relevant.
  • .Where and .ForEach are PowerShell intrinsic methods that are available on all objects. They are similar to the Where-Object and ForEach-Object commands but more efficient. Passing 'First' as the 2nd argument to .Where stops searching as soon as we have found the file.
  • Note that .Where always outputs a collection, even if only a single element matches. This is contrary to Where-Object which returns a single object if only a single element matches. So we have to write $foundFile[ 0 ] when passing it to function ExtractToFile, instead of just $foundFile which would be an array.
挽袖吟 2025-02-04 17:13:47

如果您可以并且要安装模块,则可以使用 我是该模块的维护者)。

从zip档案中提取一个或多个条目看起来像这样:

Get-ZipEntry D:\MyFolder.zip -Include */test.txt |
    Expand-ZipEntry -Destination path\to\myDestinationFolder

注意:如果 test.txt 在zip的根上,那么您只需使用 include test.txt < /代码>。另请参见 有关更多详细信息。

有关这两个cmdlet的更多示例,您可以检查文档: explion-zipentry.md#umples and get-zipentry.md#示例

If you can and want to install modules, this process can be simplified using the PSCompression Module (disclaimer: I'm the maintainer of this Module).

Extracting one or more entries from a Zip Archive would look like this:

Get-ZipEntry D:\MyFolder.zip -Include */test.txt |
    Expand-ZipEntry -Destination path\to\myDestinationFolder

Note: If the test.txt was on the Zip's root then you would simply use -Include test.txt. See also -Include for more details.

For more examples on these two cmdlets, you can check the docs: Expand-ZipEntry.md#examples and Get-ZipEntry.md#examples.

丿*梦醉红颜 2025-02-04 17:13:47

您可能只想使用Windows 10及以后的 tar

You may want to just use tar which is available in Windows 10 and later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文