web-dev-qa-db-ja.com

PowerShellを使用してZipファイル内のcsvファイルの内容を読み取る方法

いくつかのCSVファイルを含むZipファイルがあります。 PowerShellを使用してZipファイルを抽出せずにこれらのCSVファイルの内容を読み取るにはどうすればよいですか?

PowerShell Community Extensions(PSCX) の一部として含まれているRead-Archiveコマンドレットを使用しています。

これは私がこれまでに試したことです。

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

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

しかし、コードを実行すると、次のエラーメッセージが表示されますGet-Content:指定されたパスfilename.csvのオブジェクトが存在しないか、-Includeまたは-Excludeパラメーターでフィルター処理されています。

ただし、Read-Archive $fullpathを実行すると、Zipファイル内のすべてのファイルが一覧表示されます

10
Ishan

これを実現する方法は複数あります。

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()

名前(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"

アーカイブ全体の抽出には時間がかかり、一時ファイルをクリーンアップする必要があることに注意してください

3。そして、1つのファイルだけを抽出するもう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。そして、ネイティブ手段を使用するもう1つの方法:

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()
17
Andrey Marchuk

アンドレイの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() }
    }
}
0
Kino101