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

求助:基于PowerShell实现批量文件重命名结合SQL查询功能

可配置源/目标目录的批量文件处理工具解决方案

需求明确

  • 支持配置源目录(待处理文件所在)和目标目录(处理后文件输出)
  • 批量读取源目录下所有文件(含子目录)
  • 文件名解析规则:去除扩展名后,按第一个下划线分割取前半部分作为prodId
  • 通过SQL查询匹配prodId获取对应SKU值
  • 文件处理规则:将文件复制到目标目录,并重命名为原文件名主体__sku-<SKU值>.扩展名(示例:prodId--IBZ.ext → prodId--IBZ__sku-AJSJSJSJSJ.ext)

完善后的PowerShell代码

以下是修正并优化后的代码,解决了原代码的逻辑错误、参数引用错误等问题:

function Invoke-FileBatchProcessor {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$SourceDirectory,  # 源目录参数
        [Parameter(Mandatory=$true)]
        [string]$TargetDirectory,  # 目标目录参数
        [string]$SqlServer = ".",  # SQL服务器地址,默认本地
        [string]$Database = "YourDatabaseName",  # 替换为实际数据库名
        [string]$TableName = "tbl"  # 替换为实际表名
    )

    # 确保目标目录存在,不存在则创建
    if (-not (Test-Path -Path $TargetDirectory)) {
        New-Item -Path $TargetDirectory -ItemType Directory | Out-Null
    }

    # 1. 获取源目录下所有文件(含子目录)
    $files = Get-ChildItem -Path $SourceDirectory -Recurse -File

    # 2. 批量提取所有prodId,减少SQL查询次数
    $prodIds = @()
    foreach ($file in $files) {
        # 解析prodId:去扩展名后按第一个下划线分割取前半部分
        $nameWithoutExt = $file.BaseName
        $prodId = $nameWithoutExt -split "_", 2 | Select-Object -First 1
        $prodIds += $prodId
    }
    # 去重避免重复查询
    $uniqueProdIds = $prodIds | Select-Object -Unique

    # 3. 从SQL查询所有匹配的prodId与SKU映射
    $sqlQuery = @"
        SELECT prodId, sku 
        FROM $TableName 
        WHERE prodId IN ('$($uniqueProdIds -join "','")')
"@

    $connectionString = "Data Source=$SqlServer;Integrated Security=SSPI;Initial Catalog=$Database"
    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $cmd = New-Object System.Data.SqlClient.SqlCommand($sqlQuery, $connection)

    try {
        $connection.Open()
        $reader = $cmd.ExecuteReader()
        # 构建prodId到SKU的哈希表,方便快速查找
        $skuMap = @{}
        while ($reader.Read()) {
            $skuMap[$reader["prodId"]] = $reader["sku"]
        }
    }
    catch {
        Write-Error "SQL查询失败:$_"
        return
    }
    finally {
        $connection.Close()
    }

    # 4. 批量处理文件:复制并重命名
    foreach ($file in $files) {
        # 重新解析当前文件的prodId
        $nameWithoutExt = $file.BaseName
        $prodId = $nameWithoutExt -split "_", 2 | Select-Object -First 1
        
        # 检查是否找到对应SKU
        if ($skuMap.ContainsKey($prodId)) {
            $sku = $skuMap[$prodId]
            # 构建新文件名:原主体__sku-<SKU>.扩展名
            $newFileName = "$($file.BaseName)__sku-$($sku)$($file.Extension)"
            $targetPath = Join-Path -Path $TargetDirectory -ChildPath $newFileName

            # 复制文件到目标目录(避免覆盖原文件)
            Copy-Item -Path $file.FullName -Destination $targetPath -Force
            Write-Verbose "已处理文件:$($file.Name) → $newFileName"
        }
        else {
            Write-Warning "未找到prodId '$prodId' 对应的SKU,跳过文件:$($file.Name)"
        }
    }
}

# 调用示例:替换为实际目录和数据库信息
# Invoke-FileBatchProcessor -SourceDirectory "C:\SourceFiles" -TargetDirectory "C:\ProcessedFiles" -Database "YourDB"

代码关键修正点

  • 修复了原代码中错误引用$scriptPath的问题,改用传入的SourceDirectory参数
  • 优化SQL查询逻辑:批量提取并去重prodId,一次查询所有映射关系,提升处理效率(适合数千文件场景)
  • 新增目标目录自动创建逻辑
  • 修正文件处理逻辑:遍历文件而非SQL结果,实现正确的复制重命名
  • 增加错误处理和日志提示,方便排查问题

免费替代方案

如果PowerShell仍不符合需求,可选择以下两种方案:

C# 方案思路

  1. 使用Directory.EnumerateFiles遍历源目录文件
  2. 用Path.GetFileNameWithoutExtension和字符串分割解析prodId
  3. 使用SqlConnection批量查询SKU映射
  4. 用File.Copy实现文件复制并重命名,可借助并行处理提升速度(适合大文件/超大量文件场景)

Node.js 方案思路

  1. 使用fs.promises.readdir或第三方库glob遍历文件
  2. 用path.parse解析文件名,分割字符串获取prodId
  3. 使用mssql或tedious库连接SQL Server查询SKU
  4. 用fs.promises.copyFile实现文件复制重命名,异步处理适合高并发场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:09:23