0

I have a directory (2022) that has subdirectories with a date as their name (20220101, 20220102, etc).

In each subdirectory I have files that I want to archive. These files have a name that starts with either L0283 or L0284 and then numbers and dates afterwards. E.g.: L0284408.20220101.2123. The filter I want to use is L028*. I want to archive each file in the same folder that they currently live in with a zipped a folder named 400401_L0283408archive.zip or 400401_L0284408archive.zip, depending on whether it was a L0283 or L0284 file.

That archive already exists, I can write a script that deletes it first but if I can overwrite it then it would save some time. I'll be rerunning this script in multiple root directories.

I looked into powershell's Compress-Archive functionality but I couldn't figure out how to add a filter to the file name and have a different output name, plus the 0283 vs 0284 was eluding me.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
jjthemagicman
  • 85
  • 1
  • 8

2 Answers2

1

Do you have PKZip? This works:

pkzipc -add -recurse -path 400401_L0283408archive.zip 2022/L0283*
pkzipc -add -recurse -path 400401_L0284408archive.zip 2022/L0284*

Those find and archive files that match the pattern at any level in the subdirectories of 2022/.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Looks like it's attempting to add files to a new archive named 400401_L0283408archive.zip under 2022 which isn't the goal. The files that need to be archived are under 2022\20220103, 2022\20220104, etc. The end goal is for 2022\20220103 to have a zip named 400401_L0283408archive.zip and 400401_L0284408archive.zip, 2022\20220104 should also have 400401_L0283408archive.zip, 2022\20220105 should also have 400401_L0283408archive.zip, etc. Each zip should have the file that was sitting in the subdirectory, so 2022\20220103's zips should contain L0283408.20220103.2123 and L0284408.20220103.2123 – jjthemagicman Nov 15 '22 at 18:35
  • You want the zip files to contain zip files? – Mark Adler Nov 15 '22 at 19:31
1

I prefer to use the System.IO.Compression library for flexibility. You can specify the relative path within the zip file, and keep the file open for efficient writing if you prefer. However, based on your requirements it seems there will be multiple zip files (one per child folder), so I'd recommend closing the zip with Dispose() after each write. Here's an untested and inefficient example that will do what you say:

@( 'System.IO.Compression','System.IO.Compression.FileSystem') | % { [void][Reflection.Assembly]::LoadWithPartialName($_) }
Set-Location '.\2022'
$FilesToZip = Get-ChildItem 'L0283*' -File -Recurse | ?{$_.Name -notlike '*.zip'}
ForEach($file in $FilesToZip){
    Try{
        Set-Location $file.Directory.FullName #change to the folder where the file exists
        $WriteArchive = [IO.Compression.ZipFile]::Open( '.\400401_L0283408archive.zip', 'Update')#Update mode adds files to new or existing zip
        [IO.Compression.ZipFileExtensions]::CreateEntryFromFile($WriteArchive, $file.FullName, $file.Name, 'Optimal')
    }Finally{
        $WriteArchive.Dispose() #close the zip file so it can be read later     
    } 
}


$FilesToZip = Get-ChildItem 'L0284*' -File -Recurse | ?{$_.Name -notlike '*.zip'}
ForEach($file in $FilesToZip){
    Try{
        Set-Location $file.Directory.FullName #change to the folder where the file exists
        $WriteArchive = [IO.Compression.ZipFile]::Open( '.\400401_L0284408archive.zip', 'Update')#Update mode adds files to new or existing zip
        [IO.Compression.ZipFileExtensions]::CreateEntryFromFile($WriteArchive, $file.FullName, $file.Name, 'Optimal')
    }Finally{
        $WriteArchive.Dispose() #close the zip file so it can be read later     
    } 
}

It's inefficient because it opens and closes the archive with each write. I repeated code for simplicity, but if I had control over the zip file structure I would rewrite this script to create a single zip containing all the files while preserving the relative path, like I mentioned in this answer.

EDIT: I added a filter to prevent zipping *.zip files: | ?{$_.Name -notlike '*.zip'} Please try with this filter.

Rich Moss
  • 2,195
  • 1
  • 13
  • 18
  • It seems to be close to the solution but the files aren't actually getting added to the archive. I get output that looks like this: `Archive:System.IO.Compression.ZipArchive CompressedLength: ExternalAttributes: 0 FullName:L0283408.20211230:2134 LastWriteTime:11/3/2022 3:11:22 PM Length: Name:L0283408.20211230:2134 Archive:System.IO.Compression.ZipArchive CompressedLength: ExternalAttributes: 0 FullName:L0283408.20211231:5214 LastWriteTime:11/3/2022 3:11:22 PM Length: Name:L0283408.20211231:5214` ...etc – jjthemagicman Nov 15 '22 at 18:42
  • Try running it in Powershell ISE and setting a breakpoint on the `..::CreateEntryFromFile()` line. Hover over each of that function's input variables and see if they're what you expect. – Rich Moss Nov 15 '22 at 23:31
  • Try the updated script that will not try to zip up any existing archives. I hope it works :) – Rich Moss Nov 16 '22 at 21:23