PowerShell多层ForEach循环中将文件作为变量引用的问题
PowerShell 批量更新Excel文件链接脚本修复说明
核心问题修正点
- 第一层
ForEach循环语法问题:你使用的是ForEach($自定义变量 in 集合)的显式遍历语法,当前迭代的文件对象应使用你定义的$File变量引用,而非管道遍历场景下的$_自动变量 - 变量名冲突:内外层循环变量均使用
$file/$File,PowerShell变量名不区分大小写,会导致变量覆盖,需修改内层循环变量名避免冲突 - 路径引用问题:切换工作目录后相对路径会失效,所有文件操作优先使用绝对路径避免定位错误
- 多余语法错误:原代码末尾多了一个闭合的
},会导致执行报错
修复后完整代码
# 从脚本所在目录名提取周数,当前测试用固定值 # $wk = Get-Item -Path $PSScriptRoot | Select-Object -Property BaseName # $wknn = "$wk".Substring(13,2) -as [int] $wknn = 41 $wkold = $wknn-1 $wkprev = $wknn-2 # 获取脚本所在目录下所有Excel文件,使用-Filter比通配符匹配效率更高 $DefaultFiles = Get-ChildItem -Path $PSScriptRoot -Filter "*.xls*" -File ForEach($File in $DefaultFiles) { # 提前存储当前Excel文件的全路径、名称、替换后的ZIP文件名全路径 $excelFullPath = $File.FullName $excelName = $File.Name $zipFullPath = $excelFullPath -ireplace [regex]::Escape($File.Extension), ".zip" $zipName = Split-Path $zipFullPath -Leaf # 创建临时文件夹 $parent = [System.IO.Path]::GetTempPath(); [string] $guid = [System.Guid]::NewGuid(); $tempFolder = Join-Path $parent $guid; New-Item -ItemType Directory -Path $tempFolder | Out-Null # 重命名Excel文件为ZIP,使用绝对路径避免路径错误 Rename-Item -Path $excelFullPath -NewName $zipName -Force # 用7z解压到临时目录,-y参数自动覆盖确认 C:\7z\7za.exe x "$zipFullPath" -o"$tempFolder" -y # 替换rels文件内的周数,内层循环变量改名避免和外层$File冲突 $relFiles = Get-ChildItem -Path $tempFolder -Recurse -Include *.rels -File foreach ($relFile in $relFiles) { (Get-Content -Path $relFile.FullName -ErrorAction SilentlyContinue -Raw) | ForEach-Object { $_ -replace $wkold, $wknn } | ForEach-Object { $_ -replace $wkprev, $wkold } | Set-Content -Path $relFile.FullName -Force } # 切换到临时目录执行压缩操作 Set-Location -Path $tempfolder # 更新压缩包内容 C:\7z\7za.exe u -r "$zipFullPath" *.* -y # 切回脚本目录,重命名回Excel格式 Set-Location -Path $PSScriptRoot Rename-Item -Path $zipFullPath -NewName $excelName -Force }
补充注意:上述代码支持xls、xlsx、xlsm、xlsb等所有基于OpenXML格式的Excel文件,操作前建议备份原有Excel文件避免数据丢失。临时文件夹会被系统自动回收,不需要额外编写删除逻辑。
内容的提问来源于stack exchange,提问作者Kuzed
相关产品推荐
相关产品推荐

