简体   繁体   English

如何使用PowerShell读取zip文件中的csv文件的内容

[英]How to read contents of a csv file inside zip file using PowerShell

I have a zip file which contains several CSV files inside it. 我有一个zip文件,其中包含几个CSV文件。 How do I read the contents of those CSV files without extracting the zip files using PowerShell? 如何在不使用PowerShell解压缩zip文件的情况下读取这些CSV文件的内容?

I having been using the Read-Archive Cmdlet which is included as part of the PowerShell Community Extensions (PSCX) 我一直在使用Read-Archive Cmdlet作为PowerShell社区扩展(PSCX)的一部分

This is what I have tried so far. 这是我到目前为止所尝试的。

$path = "$env:USERPROFILE\Downloads\"
$fullpath = Join-Path $path filename.zip

Read-Archive $fullpath | Foreach-Object {
    Get-Content $_.Name
}

But when I run the code, I get this error message Get-Content : An object at the specified path filename.csv does not exist, or has been filtered by the -Include or -Exclude parameter. 但是当我运行代码时,我收到此错误消息Get-Content:指定路径filename.csv中的对象不存在,或者已被-Include或-Exclude参数过滤。

However, when I run Read-Archive $fullpath , it lists all the file inside the zip file 但是,当我运行Read-Archive $fullpath ,它会列出zip文件中的所有文件

There are multiple ways of achieving this: 有多种方法可以实现这一目标:

1. Here's an example using Ionic.zip dll: 1.这是使用Ionic.zip dll的示例:

clear
Add-Type -Path "E:\sw\NuGet\Packages\DotNetZip.1.9.7\lib\net20\Ionic.Zip.dll"
$zip = [Ionic.Zip.ZipFile]::Read("E:\E.zip")

$file = $zip | where-object { $_.FileName -eq "XMLSchema1.xsd"}

$stream = new-object IO.MemoryStream
$file.Extract($stream)
$stream.Position = 0

$reader = New-Object IO.StreamReader($stream)
$text = $reader.ReadToEnd()
$text

$reader.Close()
$stream.Close()
$zip.Dispose()

It's picking the file by name (XMLSchema1.xsd) and extracting it into the memory stream. 它按名称(XMLSchema1.xsd)选择文件并将其提取到内存流中。 You then need to read the memory stream into something that you like (string in my example). 然后,您需要将内存流读取为您喜欢的内容(在我的示例中为字符串)。

2. In Powershell 5, you could use Expand-Archive , see: https://technet.microsoft.com/en-us/library/dn841359.aspx?f=255&MSPPError=-2147217396 2.在Powershell 5中,您可以使用Expand-Archive ,请参阅: https//technet.microsoft.com/en-us/library/dn841359.aspx?f = 255&MSPPError = -2147217396

It would extract entire archive into a folder: 它会将整个存档提取到一个文件夹中:

Expand-Archive "E:\E.zip" "e:\t"

Keep in mind that extracting entire archive is taking time and you will then have to cleanup the temporary files 请记住,提取整个存档需要时间,然后您必须清理临时文件

3. And one more way to extract just 1 file: 3.还有一种方法可以只提取1个文件:

$shell = new-object -com shell.application
$zip = $shell.NameSpace("E:\E.zip")
$file =  $zip.items() | Where-Object { $_.Name -eq "XMLSchema1.xsd"}
$shell.Namespace("E:\t").copyhere($file)

4. And one more way using native means: 4.使用本机方式的另一种方法:

Add-Type -assembly "system.io.compression.filesystem"
$zip = [io.compression.zipfile]::OpenRead("e:\E.zip")
$file = $zip.Entries | where-object { $_.Name -eq "XMLSchema1.xsd"}
$stream = $file.Open()

$reader = New-Object IO.StreamReader($stream)
$text = $reader.ReadToEnd()
$text

$reader.Close()
$stream.Close()
$zip.Dispose()

Based on 4. solution of Andrey, I propose the following function: 根据安德烈的解决方案,我提出以下功能:

(keep in mind that "ZipFile" class exists starting at .NET Framework 4.5) (请记住,从.NET Framework 4.5开始存在“ZipFile”类)

Add-Type -assembly "System.IO.Compression.FileSystem"

function Read-FileInZip($ZipFilePath, $FilePathInZip) {
    try {
        if (![System.IO.File]::Exists($ZipFilePath)) {
            throw "Zip file ""$ZipFilePath"" not found."
        }

        $Zip = [System.IO.Compression.ZipFile]::OpenRead($ZipFilePath)
        $ZipEntries = [array]($Zip.Entries | where-object {
                return $_.FullName -eq $FilePathInZip
            });
        if (!$ZipEntries -or $ZipEntries.Length -lt 1) {
            throw "File ""$FilePathInZip"" couldn't be found in zip ""$ZipFilePath""."
        }
        if (!$ZipEntries -or $ZipEntries.Length -gt 1) {
            throw "More than one file ""$FilePathInZip"" found in zip ""$ZipFilePath""."
        }

        $ZipStream = $ZipEntries[0].Open()

        $Reader = [System.IO.StreamReader]::new($ZipStream)
        return $Reader.ReadToEnd()
    }
    finally {
        if ($Reader) { $Reader.Dispose() }
        if ($Zip) { $Zip.Dispose() }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM