Сжатие файлов из списка с помощью PowerShell 5

У меня есть файл со списком файлов с указаниями.

Как это:

XXXXXX/sample.txt

XXXXXX/dog.txt

XXXXXX/cat.docx

ZZZZ/lamp.jpg

Как я могу сжать все файлы и сохранить файлы с подразделами.

Теперь я могу сжать все файлы, но без указания направления.

Как это:

sample.txt

dog.txt

cat.docx

lamp.jpg

Извините за мой плохой английский.

5 ответов

foreach ($filename in Get-Content .\ListOfFilesToZip.txt)
{
    Compress-Archive -Update $filename .\ZipFile.zip
}

Следующая функция может сжимать всю структуру папок в один zip-файл и сохранять структуру внутри zip-файла (даже работает с PowerShell <5).

function createZipFile($outputFileName, $sourceDirectory){
    Add-Type -AssemblyName System.IO.Compression.FileSystem
    $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
    [System.IO.Compression.ZipFile]::CreateFromDirectory($sourceDirectory, $outputFileName, $compressionLevel, $false)
}

Назовите это так:

createZipFile "c:\temp\output.zip" "c:\folder\to\compress"
      function DirNewTemp {
    $tmpdir = (New-TemporaryFile).FullName
    Remove-Item -Force -Path $tmpdir -ErrorAction 'SilentlyContinue'
    New-Item -Type Directory $tmpdir | out-null
    return $tmpdir
}

function ZipFiles {
    param(
        [string]$Zip,
        [string[]]$FileList
    )
    write-host ""
    write-host "====================================="
    write-host "ZipFile $Zip"
    write-host "====================================="
    
    $pwd      = (Get-Location).Path     
    $tmpdir   = DirNewTemp
        
    try {
        $count = $FileList.Count
        foreach ($file in $FileList) {
            $pwd_escaped = [Regex]::Escape($pwd)        
            $save_file   = $file -replace "^${pwd_escaped}\\", "${tmpdir}\"
            $save_path   = Split-Path $save_file -Parent
            New-Item  -Force -Path $save_path -ItemType Directory | out-null
            Copy-Item -Force $file $save_file           
        }
        set-location $tmpdir        
        $dest = "$pwd\$Zip";
        write-host "Creating Zip: $dest"        
        Compress-Archive -Force -Path * -DestinationPath $dest
    }
    finally {
        write-host "cleanup"
        set-location $pwd
        remove-item -Force -Recurse -Path $tmpdir -ErrorAction 'SilentlyContinue'
    }
}

Не уверен, что есть ли лучший способ сделать это, но вы можете создать временную папку, скопировать файлы для архивации вместе с желаемой структурой папок туда, а затем просто сжать все целиком.

Посмотрите здесь (не мой код, но, кажется, именно так) для примера

Редактировать Если вопрос касается получения имени файла из пути
Самый эффективный способ - использовать регулярные выражения, но они могут быть довольно сложными, если вы не привыкли работать с ними.

Более простым способом было бы просто разделить каждую строку и выбрать последнюю часть, где имя файла:

$string = "c:\asd\qwe\zxc\dog.txt"

#Split the string on each \
    $string.Split("\") 

#This will output a list like this
c:
asd
qwe
zxc
dog.txt

Теперь мы хотим просто выбрать последнюю запись в этом списке, поскольку имя файла всегда является последним в пути. Поэтому мы используем Select Object для этого.

$string.Split("\") | Select-Object -Last 1 

Это вернет:

dog.txt

Вы можете выполнить это через foreach в своем списке, чтобы получить его для каждого элемента.

Другие вопросы по тегам