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

Ish*_*han 8 csv powershell zip archive

我有一个zip文件,其中包含几个CSV文件.如何在不使用PowerShell解压缩zip文件的情况下读取这些CSV文件的内容?

我一直在使用Read-Archive作为PowerShell社区扩展(PSCX)的一部分包含的Cmdlet

这是我到目前为止所尝试的.

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

Read-Archive $fullpath | Foreach-Object {
    Get-Content $_.Name
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行代码时,我收到此错误消息 Get-Content:指定路径filename.csv中的对象不存在,或者已被-Include或-Exclude参数过滤.

但是,当我运行时Read-Archive $fullpath,它会列出zip文件中的所有文件

And*_*huk 17

有多种方法可以实现这一目标:

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()
Run Code Online (Sandbox Code Playgroud)

它按名称(XMLSchema1.xsd)选择文件并将其提取到内存流中.然后,您需要将内存流读取为您喜欢的内容(在我的示例中为字符串).

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

它会将整个存档提取到一个文件夹中:

Expand-Archive "E:\E.zip" "e:\t"
Run Code Online (Sandbox Code Playgroud)

请记住,提取整个存档需要时间,然后您必须清理临时文件

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)
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)


Kin*_*101 5

基于Andrey的4.解决方案,我提出了以下功能:

(请记住,“ZipFile”类从 .NET Framework 4.5 开始存在)

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() }
    }
}
Run Code Online (Sandbox Code Playgroud)