Reputation: 3237
Below are my files
1. C:\Temp\src\config\1.txt
2. C:\Temp\src\logs\wowconfigls\3.txt
The user wants to include the files/folders that exactly match either canweb.war
or config
.
Thus, $itemsToInclude = "canweb.war,config"
The below approach creates a zip that includes both 1.txt and 3.txt however, it should not have included 3.txt
as it is inside the folder wowconfigls
which is not an exact match provided by the user.
Only config
should have matched.
# Set the name of the zip file including the build number
$zipFileName = "C:\Temp\package-165.zip"
cd "C:\Temp"
$itemsToInclude = "canweb.war,config"
Write-Host "itemsToInclude is- $itemsToInclude"
if (-not (Test-Path $zipFileName)) {
$null = New-Item $zipFileName -ItemType File
}
$workspace = "C:\Temp"
if ($itemsToInclude -eq '*') {
# Include all files, including files from subdirectories
Write-Host "Include all files, including files from subdirectories"
Get-ChildItem -Path $workspace -Recurse -File |
Compress-Archive -DestinationPath $zipFileName -Update -Force
} else {
# Include specific files as per the comma-separated list
Write-Host 'Include specific files as per the comma-separated list'
$pattern = $itemsToInclude.Split(',').ForEach({ [regex]::Escape($_) }) -join '|'
Write-Host "PATTERN is: $pattern"
$filesToInclude = Get-ChildItem $workspace -Recurse -File | Where-Object FullName -Match $pattern
#$filesToInclude = Get-ChildItem $workspace -Recurse -File | Where-Object { $_.FullName -eq $pattern }
#Where-Object { $_.FullName -eq $pattern }
#Where-Object FullName -eq $pattern
$filesToInclude | ForEach-Object {
$newZipEntrySplat = @{
EntryPath = $_.FullName.Substring($workspace.Length)
SourcePath = $_.FullName
Destination = $zipFileName
}
New-ZipEntry @newZipEntrySplat
}
#Compress-Archive -DestinationPath $zipFileName -Update
}
itemsToInclude is- canweb.war,config
Include specific files as per the comma-separated list
PATTERN is: canweb\.war|config
Directory: src/config/
EntryType LastWriteTime CompressedSize Size EntryName
--------- ------------- -------------- ---- ---------
Archive 12/6/2023 7:43 AM 9.00 B 7.00 B 1.rtf
Archive 12/6/2023 7:43 AM 0.00 B 0.00 B 2.docx
Directory: src/logs/wowconfigls/
EntryType LastWriteTime CompressedSize Size EntryName
--------- ------------- -------------- ---- ---------
Archive 12/6/2023 7:43 AM 0.00 B 0.00 B 3.txt
I understand that Where-Object { $_.FullName -ieq $pattern }
or Where-Object { $_.FullName -ilike $pattern }
should help but the $pattern
needs to be considered comma-separated one at a time.
Can you please suggest how can I achieve an exact match?
Upvotes: 0
Views: 66
Reputation: 104
Let's start with this: $pattern = $itemsToInclude.Split(',').ForEach({ [regex]::Escape($_) }) -join '|'
This gives you: $pattern = "canweb\.war|config"
This pattern will return *canweb.war*
and *config*
since -match
looks for the exact part of the string that matches. It's likely canweb.war
will be the last part of the file path (FullName
) and be okay.
What you need to change is to make the pattern string include more details.
$pattern = "\\canweb\.war$|\\config\\"
should return the correct files your looking for.
canweb.war
would always appear at the end of the FullName
attribute, so using $
to indicate that string should have what we are looking for at the end. For \\config\\
, we escape the folder path to match the folder itself. Although this will match startingpath\config\*
, so sub-folders would be included too.
EDIT: If the pattern needs to be generated from a CLI parameter $pattern = $itemsToInclude.Split(',').ForEach({if($_.contains('.')){[regex]::Escape($_+"$");} else { [regex]::Escape("\"+$_+"\"); } }) -join '|'
would work a little better. Single words would be treated as a folder and file.ext
will see the .
and add $
to the end to indicate it's a file.
Upvotes: 0