基于PowerShell从结构化文件夹生成SQL脚本目标路径字符串
从ZIP包提取SQL文件指定层级后的路径(PowerShell实现)
需求概述
编写PowerShell方法/函数,完成以下操作:
- 读取包含SQL文件的ZIP压缩包
- 创建临时子文件夹并解压ZIP内容
- 递归搜索所有
.sql文件 - 提取SQL文件在
IDUDatabase、ProbeDatabase等指定目录之后的层级路径,生成符合要求的新路径列表
现有基础代码
$file = "C:\patch-8.6.22.0 (1309041+1301513 +1326286 +1344064 + 1423182 + 1420074).zip" $tempFolder = Join-Path ([IO.Path]::GetTempPath()) (New-GUID).ToString('n') New-Item -Path $tempFolder -ItemType Directory -Force 1>$Null $subTemp = Join-Path -Path $tempFolder -ChildPath ([datetime]::Now.Ticks) & ${env:ProgramFiles}\7-Zip\7z.exe x $file "-o$($subTemp)" -y >$Null $sqls = (Get-ChildItem $subTemp -Include "*.sql" -Recurse) | Sort-Object Name foreach ($sql in $sqls) { write-host $sql }
当前输出示例
C:\Users\Bandit\AppData\Local\Temp\c5561501831c43cea5598ddb2cb1efd5\638158002382341059\Patches\IDUDatabase\Default Data\Domain\Changes\02012019-V7-AddFlagOfNewCustomer.sql C:\Users\Bandit\AppData\Local\Temp\c5561501831c43cea5598ddb2cb1efd5\638158002382341059\Patches\IDUDatabase\Default Data\Common\Configuration-data.sql
期望输出示例
执行以下代码后:
foreach ($sql in $Newsqls) { write-host $sql }
输出结果:
Default Data\Domain\Changes\02012019-V7-AddFlagOfNewCustomer.sql Default Data\Common\Configuration-data.sql
初步实现代码
$newsqls = @() foreach ($sql in $sqls) { $dllpath = Convert-Path($sql.PSPath) $ParentCount = ($dllpath.Split([System.IO.Path]::DirectorySeparatorChar)).count for ($i = -1; $i -gt - $ParentCount; $i--) { $parentname = $dllpath.Split([System.IO.Path]::DirectorySeparatorChar)[$i] # write-host $parentname # 可注释掉调试输出 if ($parentname -match 'IDUDatabase' -or $parentname -match 'ProbeDataBase') { $j = $i + 1 break } } $newsql = "" for ($i = $j ; $i -le -1 ; $i++) { $parentname = $dllpath.Split([System.IO.Path]::DirectorySeparatorChar)[$i] $newsql += "\" + $parentname } $newsql = $newsql.TrimStart('\') $newsqls += $newsql }
优化实现方案
可以用更简洁的逻辑实现路径截取,避免多层循环:
$targetDirs = 'IDUDatabase', 'ProbeDatabase' $newsqls = $sqls | ForEach-Object { $pathParts = $_.FullName -split [regex]::Escape([System.IO.Path]::DirectorySeparatorChar) $targetDir = $targetDirs | Where-Object { $_ -in $pathParts } if ($targetDir) { $targetIndex = $pathParts.IndexOf($targetDir) $pathParts[($targetIndex + 1)..($pathParts.Count - 1)] -join [System.IO.Path]::DirectorySeparatorChar } }
这段代码通过拆分路径为数组,定位目标目录的位置后直接截取后续部分并拼接,逻辑更清晰高效。
内容的提问来源于stack exchange,提问作者Bandit
相关产品推荐
相关产品推荐

