You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中实现Zip压缩的精准文件/文件夹匹配需求

问题背景

现有文件列表:

1. C:\Temp\src\config\1.txt
2. C:\Temp\src\logs\wowconfigls\3.txt

用户需求:在PowerShell中创建Zip压缩包时,仅包含完全匹配canweb.war文件或config文件夹下的所有内容,因此设置$itemsToInclude = "canweb.war,config"。

现有问题

当前脚本错误地将3.txt纳入了压缩包,因为该文件所在的wowconfigls文件夹名称包含config子串,但用户要求的是精准匹配config文件夹,仅应包含config文件夹下的文件。

现有脚本及执行结果

脚本代码

# 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    
需求咨询

已知使用Where-Object { $_.FullName -ieq $pattern }或Where-Object { $_.FullName -ilike $pattern }可能实现精准匹配,但需对逗号分隔的匹配项逐一处理,请问如何实现该精准匹配需求?


解决方案

要实现精准匹配,需分别处理文件和文件夹两种匹配场景,避免子串误匹配。核心思路是拆分匹配项后,逐个判断文件是否符合以下任一条件:

  1. 文件名完全匹配目标文件(如canweb.war)
  2. 文件位于精准匹配的目标文件夹(如config)或其子目录下

修改后的完整脚本

# 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'
  # 拆分并清理匹配项,去除多余空格
  $includeItems = $itemsToInclude.Split(',') | ForEach-Object { $_.Trim() }

  $filesToInclude = Get-ChildItem $workspace -Recurse -File | Where-Object {
      $currentFile = $_
      # 遍历每个匹配项,满足任一条件则保留该文件
      $includeItems | ForEach-Object {
          $targetItem = $_
          # 场景1:文件名完全匹配目标文件
          if ($currentFile.Name -eq $targetItem) {
              return $true
          }
          # 场景2:文件位于精准匹配的目标文件夹下
          $targetFolder = Join-Path $workspace $targetItem
          # 检查文件路径是否以目标文件夹路径开头,确保是精准目录下的内容
          if ($currentFile.FullName.StartsWith($targetFolder, [System.StringComparison]::OrdinalIgnoreCase)) {
              return $true
          }
      }
      # 无匹配项则排除
      return $false
  }

  $filesToInclude | ForEach-Object {
    $newZipEntrySplat = @{
      EntryPath   = $_.FullName.Substring($workspace.Length)
      SourcePath  = $_.FullName
      Destination = $zipFileName
    }
    New-ZipEntry @newZipEntrySplat
  }
}

关键说明

  • 使用Join-Path构造目标文件夹路径,避免手动拼接路径时的分隔符错误
  • 通过StartsWith判断文件是否在目标文件夹或其子目录下,彻底避免名称包含config的其他文件夹被误匹配
  • 文件名匹配使用精准的-eq运算符,确保只有完全同名的文件被纳入

内容的提问来源于stack exchange,提问作者Ashar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:32:34