Windows环境下提取WAV文件末尾嵌入XML元数据的方法求助
解决WAV文件末尾XML元数据批量提取并生成Excel列表的问题
修正后的PowerShell脚本
$directory = "C:\test" $outputCsv = "C:\test\call_metadata.csv" $results = @() # 定义XML起始和结束标记的字节序列 $startTagBytes = [System.Text.Encoding]::UTF8.GetBytes("<recording>") $endTagBytes = [System.Text.Encoding]::UTF8.GetBytes("</recording>") $wavFiles = Get-ChildItem -Path $directory -Filter *.wav foreach ($file in $wavFiles) { Write-Host "Processing file: $($file.Name)" $fileBytes = [System.IO.File]::ReadAllBytes($file.FullName) # 从文件末尾逆向查找结束标记 $endIndex = -1 for ($i = $fileBytes.Length - $endTagBytes.Length; $i -ge 0; $i--) { $match = $true for ($j = 0; $j -lt $endTagBytes.Length; $j++) { if ($fileBytes[$i + $j] -ne $endTagBytes[$j]) { $match = $false break } } if ($match) { $endIndex = $i + $endTagBytes.Length break } } if ($endIndex -eq -1) { Write-Host "No </recording> tag found in $($file.Name)" $results += [PSCustomObject]@{ Filename = $file.Name Status = "XML not found" } continue } # 从结束标记位置逆向查找起始标记 $startIndex = -1 for ($i = $endIndex - $startTagBytes.Length; $i -ge 0; $i--) { $match = $true for ($j = 0; $j -lt $startTagBytes.Length; $j++) { if ($fileBytes[$i + $j] -ne $startTagBytes[$j]) { $match = $false break } } if ($match) { $startIndex = $i break } } if ($startIndex -eq -1) { Write-Host "No <recording> tag found in $($file.Name)" $results += [PSCustomObject]@{ Filename = $file.Name Status = "XML start tag missing" } continue } # 提取XML字节并转换为UTF8字符串 $xmlBytes = $fileBytes[$startIndex..($endIndex - 1)] $xmlContent = [System.Text.Encoding]::UTF8.GetString($xmlBytes) try { # 解析XML节点 $xml = [xml]$xmlContent $recordingNode = $xml.SelectSingleNode("//recording") # 按实际XML结构提取元数据,自行调整字段 $metadata = [PSCustomObject]@{ Filename = $file.Name CallID = $recordingNode.callID FromNumber = $recordingNode.fromNumber ToNumber = $recordingNode.toNumber StartTime = $recordingNode.startTime Duration = $recordingNode.duration # 新增其他需要的字段 } $results += $metadata Write-Host "Successfully extracted metadata from $($file.Name)" } catch { Write-Host "Failed to parse XML in $($file.Name): $_" $results += [PSCustomObject]@{ Filename = $file.Name Status = "XML parse error: $_" } } } # 导出为CSV(Excel可直接打开) $results | Export-Csv -Path $outputCsv -NoTypeInformation -Encoding UTF8 Write-Host "Done! Metadata exported to $outputCsv"
原代码失败原因
- 二进制转码乱码:WAV音频部分是二进制数据,直接转UTF8字符串会产生大量无效字符,破坏XML标签结构,导致正则无法匹配。
- 正则匹配限制:原正则使用
.+?,默认不匹配换行符,若XML包含换行则匹配失败。 - 低效全量读取:读取整个大文件的二进制内容转成字符串,完全没必要处理音频部分,浪费资源。
解决方案核心要点
- 逆向字节匹配:从文件末尾查找
</recording>标记,再向前定位<recording>,只提取XML部分的字节,避开音频二进制数据。 - 字节级精准匹配:直接操作文件字节,避免编码转换带来的乱码问题,确保标记匹配准确。
- 容错处理:添加
try-catch捕获XML解析错误,单个文件失败不会终止整个批量任务。 - 无额外依赖:使用Windows原生PowerShell命令,导出的CSV文件可直接用Excel打开,无需安装任何额外软件。
使用说明
- 将脚本保存为
Extract-WavMetadata.ps1。 - 修改
$directory为你的WAV文件所在文件夹路径,$outputCsv为导出CSV的路径。 - 根据你的实际XML结构,调整脚本中
$metadata的字段(比如XML节点是<call_id>就改成$recordingNode.call_id)。 - 打开PowerShell,进入脚本所在目录,运行命令:
.\Extract-WavMetadata.ps1。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

