【问题标题】:Archive all files of a certain type recursively from powershell从powershell递归归档某种类型的所有文件
【发布时间】:2019-02-20 00:44:14
【问题描述】:

有没有办法使用 Compress-Archive 脚本,当从路径运行时:

  1. 存档与通配符过滤器匹配的所有文件(例如 *.doc)
  2. 将此类文件存档在当前文件夹和所有子文件夹中
  3. 保存相对文件夹结构(不过,使用相对或绝对的选项会很好)

我很难让它同时完成所有这三个。

编辑:

以下过滤器和递归,但不维护文件夹结构

Get-ChildItem -Path ".\" -Filter "*.docx" -Recurse |
Compress-Archive -CompressionLevel Optimal -DestinationPath "$pwd\doc.archive-$(Get-Date -f yyyyMMdd.hhmmss).zip"

此项不递归:

Compress-Archive -Path "$pwd\*.docx" -CompressionLevel Optimal -DestinationPath "$pwd\doc.archive-$(Get-Date -f yyyyMMdd.hhmmss).zip"

在某个时候,我有一个命令会递归但不会过滤,但现在无法返回。

【问题讨论】:

    标签: windows powershell archive compress-archive


    【解决方案1】:

    不幸的是,从 Windows PowerShell v5.1 / PowerShell Core 6.1.0 开始,Compress-Archive 非常有限:

    • 保留子目录树的唯一方法是将目录路径传递给Compress-Archive。

      • 很遗憾,这样做不提供包含/排除机制,只能选择文件的子集。

      • 此外,生成的存档将在内部包含为输入目录命名的单个根目录(例如,如果您将C:\temp\foo 传递给Compress-Archive,则生成的存档将包含一个包含输入目录子树的单个 foo 目录 - 而不是在顶层包含 C:\temp\foo 的 内容。

      • 没有保留绝对路径的选项。

    • 一个麻烦的解决方法是创建目录树的临时副本,只包含感兴趣的文件(Copy-Item -Recurse -Filter *.docx . $env:TEMP\tmpDir; Compress-Archive $env:TEMP\tmpDir out.zip - 请注意为空 em> dirs. 将包括在内)

      • 考虑到您仍然会始终以存档中的输入目录命名的单个根目录结束,即使这可能不适合您 - 请参阅底部的替代方案。

    替代品可能会更好:


    直接使用.NET v4.5+[System.IO.Compression.ZipFile]类解决问题:

    注意:

    • 在 Windows PowerShell 中,与 PowerShell Core 不同,您大多数情况下使用 Add-Type -AssemblyName System.IO.Compression 手动加载相关程序集。

    • 由于 PowerShell 从 Windows PowerShell v5.1 / PowerShell Core 6.1.0 开始不支持 隐式 使用扩展方法,因此您必须显式使用 [System.IO.Compression.ZipFileExtensions] 类作为好吧。

    # Windows PowerShell: must load assembly System.IO.Compression manually.
    Add-Type -AssemblyName System.IO.Compression
    
    # Create the target archive via .NET to provide more control over how files
    # are added.
    # Make sure that the target file doesn't already exist.
    $archive = [System.IO.Compression.ZipFile]::Open(
      "$pwd\doc.archive-$(Get-Date -f yyyyMMdd.hhmmss).zip",
      'Create'
    )
    
    # Get the list of files to archive with their relative paths and
    # add them to the target archive one by one.
    $useAbsolutePaths = $False # Set this to true to use absolute paths instead.
    Get-ChildItem -Recurse -Filter *.docx | ForEach-Object {
        # Determine the entry path, i.e., the archive-internal path.
        $entryPath = (
              ($_.FullName -replace ([regex]::Escape($PWD.ProviderPath) + '[/\\]'), ''), 
              $_.FullName
            )[$useAbsolutePaths]
        $null = [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
          $archive, 
          $_.FullName, 
          $entryPath
        )
      }
    
    # Close the archive.
    $archive.Dispose()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 2020-04-12
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      相关资源
      最近更新 更多