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

如何使用PowerShell在Azure Blob中合并同关键词带时间戳的文本/CSV文件

使用PowerShell合并Azure Blob中同关键词的CSV/文本文件并迁移

当然有成熟的PowerShell方案来实现这个需求!结合Azure PowerShell的Az.Storage模块,我们可以完成Blob文件的筛选、合并、上传(迁移)全流程,完美适配你布局一致的CSV/文本文件场景。下面是一步步的实操指南:

前置准备

首先确保你已经安装了Az.Storage模块,并且能正常访问你的Azure存储账户:

# 安装Az.Storage模块(如果未安装)
Install-Module -Name Az.Storage -Force -AllowClobber
# 登录Azure账号(如果未登录)
Connect-AzAccount

完整实现步骤

1. 配置存储账户与路径参数

先定义好你的存储账户、容器、文件夹以及要匹配的关键词:

# 替换为你的实际信息
$storageAccountName = "your-storage-account-name"
$sourceContainer = "source-container"
$sourceFolderPath = "source-folder/" # 注意末尾的斜杠
$targetContainer = "target-container"
$targetFolderPath = "target-folder/"
$targetKeyword = "sales-data" # 替换为你要匹配的文件名关键词

2. 获取存储上下文并筛选目标Blob

连接到存储账户,筛选出所有包含指定关键词的Blob文件:

# 获取存储上下文(这里用Azure AD认证,也可以用存储密钥)
$storageCtx = Get-AzStorageAccount -Name $storageAccountName | Select-Object -ExpandProperty Context

# 筛选源文件夹下包含关键词的Block Blob
$blobsToMerge = Get-AzStorageBlob -Container $sourceContainer -Context $storageCtx | 
    Where-Object { 
        $_.Name -like "$sourceFolderPath*$targetKeyword*" -and 
        $_.BlobType -eq "BlockBlob" 
    }

# 如果没有找到匹配的文件,提前退出
if (-not $blobsToMerge) {
    Write-Host "No blobs matching keyword '$targetKeyword' found in source folder."
    exit
}

3. 下载Blob到本地临时目录

将筛选出的Blob下载到本地临时目录,方便后续合并:

$tempWorkingDir = Join-Path -Path $env:TEMP -ChildPath "BlobMerge_$(Get-Date -Format 'yyyyMMddHHmmss')"
New-Item -Path $tempWorkingDir -ItemType Directory -Force | Out-Null

# 批量下载Blob到临时目录
foreach ($blob in $blobsToMerge) {
    $localFileName = $blob.Name.Split('/')[-1] # 提取文件名(去掉文件夹路径)
    $localFilePath = Join-Path -Path $tempWorkingDir -ChildPath $localFileName
    Get-AzStorageBlobContent -Blob $blob.Name -Container $sourceContainer -Context $storageCtx -Destination $localFilePath -Force | Out-Null
    Write-Host "Downloaded: $localFileName"
}

4. 合并文件(处理CSV表头重复问题)

因为你的文件是布局一致的CSV,我们需要避免重复写入表头——只保留第一个文件的表头,后续文件跳过第一行:

# 生成合并后的文件名(带时间戳避免重复)
$mergedFileName = "merged_$targetKeyword_$(Get-Date -Format 'yyyyMMddHHmmss').csv"
$mergedFilePath = Join-Path -Path $tempWorkingDir -ChildPath $mergedFileName

$isFirstFile = $true
# 按文件时间戳排序(确保合并顺序符合时间逻辑)
Get-ChildItem -Path $tempWorkingDir -Filter "*$targetKeyword*" | Sort-Object LastWriteTime | ForEach-Object {
    if ($isFirstFile) {
        # 第一个文件完整写入(包含表头)
        Get-Content $_.FullName | Add-Content $mergedFilePath
        $isFirstFile = $false
        Write-Host "Added full content of: $($_.Name)"
    } else {
        # 后续文件跳过第一行(表头)
        Get-Content $_.FullName | Select-Object -Skip 1 | Add-Content $mergedFilePath
        Write-Host "Added content (skip header) of: $($_.Name)"
    }
}

# 如果是纯文本文件(无表头),直接用下面的命令替代上面的块:
# Get-ChildItem -Path $tempWorkingDir -Filter "*$targetKeyword*" | Sort-Object LastWriteTime | Get-Content | Add-Content $mergedFilePath

5. 上传合并后的文件到目标Blob

将合并好的文件上传到指定的目标容器和文件夹:

$targetBlobPath = Join-Path -Path $targetFolderPath -ChildPath $mergedFileName
Set-AzStorageBlobContent -File $mergedFilePath -Container $targetContainer -Blob $targetBlobPath -Context $storageCtx -Force | Out-Null
Write-Host "Successfully uploaded merged file to: $targetBlobPath"

6. 可选:完成源文件的迁移/清理

如果你需要把源文件迁移到其他位置(比如归档文件夹)或者删除,可以执行以下操作:

# 示例1:将源Blob移动到源容器的归档文件夹
$archiveFolderPath = "$sourceFolderPath/archived/"
foreach ($blob in $blobsToMerge) {
    $newBlobName = $blob.Name.Replace($sourceFolderPath, $archiveFolderPath)
    Start-AzStorageBlobCopy -SrcBlob $blob.Name -SrcContainer $sourceContainer -DestBlob $newBlobName -DestContainer $sourceContainer -Context $storageCtx | Out-Null
    # 等待复制完成后删除源Blob(可选)
    # Remove-AzStorageBlob -Blob $blob.Name -Container $sourceContainer -Context $storageCtx -Force
}

# 示例2:直接删除源Blob(如果不需要保留)
# Remove-AzStorageBlob -Blob $blobsToMerge.Name -Container $sourceContainer -Context $storageCtx -Force

注意事项

  • 大文件处理:如果你的Blob文件非常大,本地下载合并可能会占用较多磁盘空间,这种情况下可以考虑使用Azure Functions结合Blob触发器,直接在云端处理(无需下载到本地)。
  • 认证安全:优先使用Azure AD认证(Connect-AzAccount),避免硬编码存储密钥,提升安全性。
  • 排序逻辑:代码中按文件的LastWriteTime排序,如果你需要按文件名中的时间戳排序,可以修改Sort-Object的参数,比如Sort-Object { [datetime]::ParseExact($_.Name.Split('-')[1], 'yyyyMMdd', $null) }(根据你的文件名格式调整)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:46:51