Извлечение Specifi c типов файлов из нескольких Zip-файлов в одну папку в Powershell - PullRequest
1 голос
/ 26 марта 2020

У меня есть несколько zip-файлов, которые содержат несколько типов файлов. Единственные, которые меня интересуют - это файлы .txt. Мне нужно только извлечь файлы .txt и поместить их в собственную папку, игнорируя все другие типы файлов в файлах zips.

Все файлы zip находятся в одной папке.

Пример

-foo.zip

--1.aaa
--2.bbb
--3.ccc
--4.txt

-foo2.zip

--5.aaa
--6.bbb
--7.ccc
--8.txt

Я хочу извлечь 4.txt и 8.txt в другую папку. Я не могу на всю жизнь понять это и целую вечность смотреть, гуглить и пытаться. Даже умудряется время от времени удалять в почтовые индексы: -)

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 26 марта 2020

Используйте тип ZipArchive для программной проверки архива перед извлечением:

Add-Type -AssemblyName System.IO.Compression

$destination = "C:\destination\folder"

# Locate zip file
$zipFile = Get-Item C:\path\to\file.zip

# Open a read-only file stream
$zipFileStream = $zipFile.OpenRead()

# Instantiate ZipArchive
$zipArchive = [System.IO.Compression.ZipArchive]::new($zipFileStream)

# Iterate over all entries and pick the ones you like
foreach($entry in $zipArchive.Entries){
    if($entry.Name -like '*.txt'){
        # Create new file on disk, open writable stream
        $targetFileStream = $(
            New-Item -Path $destination -Name $entry.Name -ItemType File
        ).OpenWrite()

        # Open stream to compressed file, copy to new file stream
        $entryStream = $entry.Open()
        $entryStream.BaseStream.CopyTo($targetFileStream)

        # Clean up
        $targetFileStream,$entryStream |ForEach-Object Dispose
    }
}

# Clean up
$zipArchive,$zipFileStream |ForEach-Object Dispose

Повторите для каждого zip-файла.

Обратите внимание, что приведенный выше код имеет очень минимальная обработка ошибок , и должна читаться как пример

0 голосов
/ 26 марта 2020

Вот один из подходов:

  1. Go через каждый .zip файл в папке.
  2. Извлечение архива в отдельную папку.
  3. Извлечение .txt файл из папки.
  4. Копирование файлов в папку назначения, содержащую все .txt файлы. Это перезапишет файлы, если они уже существуют в папке назначения.
  5. Очистка извлеченных папок после завершения.

Демонстрация:

function Copy-ZipArchiveFiles {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [ValidateScript({
            if (-not(Test-Path $_ -PathType Container))
            {
                throw "The source path $_ does not exist. Please enter a valid source path."
            }
            else
            {
                $true
            }
        })]
        [string]$Path,
        [Parameter(Mandatory=$true)]
        [ValidateScript({
            if ([string]::IsNullOrEmpty($_.Trim()))
            {
                throw "The Destination path is null or empty. Please enter a valid destination path."
            } 
            else 
            {
                $true
            }
        })]
        [string]$Destination,
        [Parameter(Mandatory=$false)]
        [AllowNull()]
        [AllowEmptyString()]
        [AllowEmptyCollection()]
        [string[]]$Include
    )

    # Create destination folder if it doesn't already exist
    if (-not(Test-Path -Path $Destination -PathType Container))
    {
        try 
        {
            New-Item -Path $Destination -ItemType Directory -ErrorAction Stop
        }
        catch
        {
            throw "The destination path $Destination is invalid. Please enter a valid destination path."
        }
    }

    # Go through each .zip file
    foreach ($zipFile in Get-ChildItem -Path $Path -Filter *.zip)
    {

        # Get folder name from zip file w/o .zip at the end
        $zipFolder = Split-Path $zipFile -LeafBase

        # Get full folder path
        $folderPath = Join-Path -Path $Path -ChildPath $zipFolder

        # Expand .zip file into folder if it doesn't exist
        if (-not(Test-Path -Path $folderPath -PathType Container)) 
        {
            Expand-Archive -Path $zipFile.FullName -DestinationPath $folderPath
        }

        # Copy files into destination folder
        foreach ($file in Get-ChildItem $folderPath -Include $Include -Recurse)
        {
            Copy-Item -Path $file.FullName -Destination $Destination
        }

        # Delete extracted folders
        Remove-Item -Path $folderPath -Recurse -Force
    }
}

Использование:

Copy-ZipArchiveFiles `
    -Path "C:\path\to\zip\files" `
    -Destination "C:\path\to\text\files" `
    -Include "*.txt"

Примечание: Можно также использовать это для нескольких типов расширений, передавая -Include *.txt, *.pdf. Я также немного перегружен проверкой ошибок параметров, но верю в написание надежного кода. В любом случае, это хорошая привычка, когда вы пишете свои собственные командлеты:)

0 голосов
/ 26 марта 2020

Попробуйте это:

Set-Location "Extraction path"
@("full path of foo.zip","full path of foo2.zip") | ForEach {
  & "Full path of 7z.exe" x '-i!*.txt' $_.FullName
}
  • Устанавливает путь к пути, в который будут извлечены файлы.

  • Передает массив файлов zip to for l oop.

  • Выполнить команду 7z для извлечения только zip-файлов.

...