excel - 在多个 ForEach 循环中将文件称为变量 [PowerShell]
问题描述
我在我的脚本上取得了一些进展,该脚本会自动更新 excel 文件中的链接而不打开它们。我已经成功地使该函数在单个文件上工作,并输入文件名和要替换的文本。现在我正在尝试扩展它,以便它对脚本目录中的所有文件执行相同的操作。
以下是脚本如何与步骤注释一起使用:
# This part will be responsible from fetching the week number to replace from the script directory name, currently I am testing with pre-determined number
# $wk = Get-Item -Path $PWD | Select-Object -Property BaseName
# $wknn = "$wk".Substring(13,2) -as [int]
$wknn = 41
$wkold = $wknn-1
$wkprev = $wknn-2
$DefaultFiles = Get-ChildItem | Where-Object {$_.Name -like "*.xls*"}
ForEach($File in $DefaultFiles)
{
# Build ZIP file name
$zipFile = $_ -ireplace [regex]::Escape(".xlsb"), ".zip"
# Create temporary folder
$parent = [System.IO.Path]::GetTempPath();
[string] $guid = [System.Guid]::NewGuid();
$tempFolder = Join-Path $parent $guid;
New-Item -ItemType Directory -Path $tempFolder;
# Rename file to ZIP
Rename-Item -Path $_ -NewName $zipFile
# Not using Expand-Archive because it changes the ZIP format
C:\7z\7za.exe x "$zipFile" -o"$tempFolder"
# Replace old text with new text. First replace wk-1 to wk and then wk-2 to wk-1
$fileNames = Get-ChildItem -Path $tempFolder -Recurse -Include *.rels
foreach ($file in $fileNames)
{
(Get-Content -ErrorAction SilentlyContinue $file.FullName) |
Foreach-Object { $_ -replace $wkold, $wknn } |
Foreach-Object { $_ -replace $wkprev, $wkold } |
Set-Content $file.FullName
}
# Changing working folder because 7Zip option -w doesn't work
Set-Location -Path $tempfolder
# Update archive with new files. Not using Compress-Archive because it changes the ZIP format
C:\7z\7za.exe u -r "$zipFile" *.*
# Rename file back to XLSB
Rename-Item -Path $zipFile -NewName $_
#Move the final .xlsb file back to the script root
move-Item -Path $_ -destination $PSScriptRoot
#Set location to script root to start over
Set-Location -Path $PSScriptRoot
}
}
我遇到了 forEach 循环的问题。我不确定如何在 Build Zip File Name 步骤的第一个循环中引用文件名。之后我想将输出文件移动到脚本根目录时如何引用它。此外,我怀疑 forEach 循环的堆叠可能不那么简单,并且需要在代码中执行额外的步骤,但由于我刚开始使用 CI 没有经验并且找不到我的问题的简单答案。
我非常感谢对我的代码中的语法提供一些帮助:)
解决方案
我会在主循环之外创建一个临时文件夹并将工作目录设置为该文件夹。然后删除文件夹并在所有完成后重置工作目录。
此外,无需先重命名完成的 zip 文件,然后再将其移回其原始位置,因为您可以同时使用Move-Item
cmdlet 执行此操作。
尝试:
$wknn = 41
$wkold = $wknn - 1
$wkprev = $wknn - 2
$7zipExe = 'C:\7z\7za.exe' # path to 7za.exe
$sourcePath = $PSScriptRoot # path to where the Excel files are
# Create temporary folder
$tempFolder = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ((New-Guid).Guid)
$null = New-Item -ItemType Directory -Path $tempFolder -Force
# retrieve a collection of Excel files (FullNames only).
# If you ONLY want .xlsb files, set the Filter to '*.xlsb'
$excelFiles = (Get-ChildItem -Path $sourcePath -Filter '*.xls*' -File).FullName
# Changing working folder because 7Zip option -w doesn't work
Set-Location -Path $tempfolder
foreach($File in $excelFiles) {
# Build ZIP file name
$zipFile = [System.IO.Path]::ChangeExtension($File, '.zip')
# Rename file to ZIP
Rename-Item -Path $File -NewName $zipFile
# Not using Expand-Archive because it changes the ZIP format
& $7zipExe x "$zipFile" -o"$tempFolder" | Out-Null
# Replace old text with new text. First replace wk-1 to wk and then wk-2 to wk-1
Get-ChildItem -Path $tempFolder -Recurse -Filter '*.rels' -File | ForEach-Object {
(Get-Content -Path $_.FullName -Raw) -replace $wkold, $wknn -replace $wkprev, $wkold |
Set-Content $_.FullName
}
# Update archive with new files. Not using Compress-Archive because it changes the ZIP format
& $7zipExe u -r "$zipFile" *.* | Out-Null
# Rename and Move the updated file back to the original location (overwrite)
Move-Item -Path $zipFile -Destination $File -Force
# remove all files from the temporary folder to start fresh
Remove-Item -Path "$tempfolder\*" -Recurse -Force
}
# Set location back to script root
Set-Location -Path $PSScriptRoot
# remove the temporary folder
Remove-Item -Path $tempfolder -Recurse -Force
推荐阅读
- python - 在 pyplot 中绘制颜色比例
- javascript - 如何使使用 DOM 选择绘制 svg 的 D3js 应用程序在同一页面上的多个选项卡中工作?
- ant-media-server - 如何更改 Ant Media Server 服务的最大堆大小?
- python - API 连接 HTTP 400
- shell - 通过 jenkins 执行脚本返回错误
- blockchain - 无法在智能合约 tron 区块链中调用函数
- javascript - 如何通过 JavaScript 中的特定键删除 Algolia 中的对象?
- checkbox - 我想根据条件在 ag-grid 中选择行(复选框)
- c++ - 实现模板类 Stack
- c# - 从字节数组返回 PDF 作为 FileContentResult 会产生无效文件