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

如何在PowerShell 7.x中按含路径的通配符列表复制文件及目录

在PowerShell 7.x实现类似rsync的路径筛选复制

要实现你需要的「按部分路径(含通配符、文件/文件夹)筛选源目录,复制到目标目录并保留结构」的功能,Copy-Item的-Include/-Filter确实不好用——它们只对最后一级文件名/文件夹名生效,没法匹配完整相对路径。下面给你两种可行的实现方式:

方法1:原生PowerShell cmdlet实现

先定义好源目录、目标目录和要筛选的路径模式:

$sourceDir = "/path/to/source"
$destDir = "/path/to/destination"
# 模式和bash脚本一致,支持通配符*
$includePatterns = @(
    "CMake/somefilepattern*",
    "include/somefile.h",
    "source/somefolder/*"
)

然后遍历源目录所有文件,筛选符合模式的项并复制:

# 处理文件复制,保留目录结构
Get-ChildItem -Path $sourceDir -Recurse -File | ForEach-Object {
    # 获取文件相对于源目录的路径
    $relativePath = $_.FullName.Substring($sourceDir.Length + 1)
    # 检查是否匹配任意指定模式
    foreach ($pattern in $includePatterns) {
        if ($relativePath -like $pattern) {
            # 构建目标文件路径
            $destFilePath = Join-Path $destDir $relativePath
            # 先创建目标文件夹(不存在则自动创建)
            New-Item -ItemType Directory -Path (Split-Path $destFilePath -Parent) -Force | Out-Null
            # 复制文件
            Copy-Item -Path $_.FullName -Destination $destFilePath -Force
            break
        }
    }
}

# 处理空文件夹:如果模式包含带/*的文件夹,确保空文件夹也被复制
foreach ($pattern in $includePatterns) {
    if ($pattern.EndsWith("/*")) {
        $folderPath = $pattern.Substring(0, $pattern.Length - 2)
        $sourceFolder = Join-Path $sourceDir $folderPath
        if (Test-Path $sourceFolder -PathType Container) {
            $destFolder = Join-Path $destDir $folderPath
            New-Item -ItemType Directory -Path $destFolder -Force | Out-Null
        }
    }
}

核心细节

  • 相对路径匹配:通过计算文件相对于源目录的路径,才能用-like匹配你指定的完整模式
  • 空文件夹处理:Get-ChildItem -File不会遍历空文件夹,所以需要单独处理带/*的模式
  • 通配符支持:PowerShell的-like支持*(匹配任意字符)和?(匹配单个字符),和bash通配符逻辑一致

方法2:用Robocopy(更高效)

Robocopy是Windows自带的高效文件复制工具,PowerShell里直接调用即可,它天生支持路径模式筛选,比原生cmdlet快很多,适合大量文件的场景:

$sourceDir = "/path/to/source"
$destDir = "/path/to/destination"
$includePatterns = @(
    "CMake\somefilepattern*",
    "include\somefile.h",
    "source\somefolder\*"
)

# /E:复制所有子目录(含空目录);/MT:启用多线程;/INCLUDE:指定筛选模式
robocopy $sourceDir $destDir /E /MT /INCLUDE:$($includePatterns -join ',')

核心细节

  • /E 参数保证目录结构完整,包括空文件夹
  • /INCLUDE 支持多个模式,用逗号分隔即可
  • /MT 启用多线程复制,默认8线程,可加数字指定(如/MT:16)
  • Robocopy路径分隔符用\更稳妥,PowerShell也能识别/,但避免跨平台问题优先用\

为什么Copy-Item的参数不好用?

Copy-Item的-Include和-Filter只作用于最后一级路径元素,比如你写Copy-Item -Path $sourceDir\* -Include "include/somefile.h" -Recurse,它只会找文件名是include/somefile.h的文件,而不是路径里包含这个字符串的文件——这就是你之前失败的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:01:14