Сжатие файлов из списка с помощью 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 в своем списке, чтобы получить его для каждого элемента.