删除Powershell中的注解块

qyuhtwio  于 2022-12-26  发布在  Shell
关注(0)|答案(3)|浏览(147)

我使用下面的代码来处理SQL脚本,并使用GO命令将其拆分:

[string]$batchDelimiter = "[gG][oO]"

$scriptContent = Get-Content $sqlScript | Out-String
$batches = $scriptContent -split "\s*$batchDelimiter\s*\r?\n"
foreach($batch in $batches)
{
    if(![string]::IsNullOrEmpty($batch.Trim()))
    {
        $SqlCmd.CommandText = $batch
        $reader = $SqlCmd.ExecuteNonQuery()
    }
}

我遇到的问题是,当GO命令出现在注解块中间时:

/*
IF OBJECT_ID('AmyTempMapRetroDateFK') IS NOT NULL
DROP FUNCTION AmyTempMapRetroDateFK
GO
*/

有没有办法在处理脚本之前删除所有的注解块?我在c#中看到过一些例子,但在Powershell中没有。

hsvhsicv

hsvhsicv1#

假设没有 * nested * 注解(PSv3+语法):

(Get-Content -Raw $sqlScript) -split '(?s)/\*.*?\*/' -split '\r?\ngo\r?\n' -notmatch '^\s*$' |
  ForEach-Object { $SqlCmd.CommandText = $_.Trim(); $reader = $SqlCmd.ExecuteNonQuery() }

注意:如果最后一行可能没有以换行符结束,请使用'\r?\ngo(\r?\n|$)而不是
'\r?\ngo\r?\n'

  • Get-Content -Raw自PSv3开始提供,它将整个文件读取到一个 * 单个 * 字符串中-它是Get-Content $sqlScript | Out-String的更简单、更高效的等价物
  • -split '(?s)/\*.*?\*/'将输入字符串拆分为/* ... */个跨度;注意内联选项(?s),它也是使.匹配换行符所必需的;需要非贪婪量词.*?来仅匹配到 * 下一个 * */示例;结果是排除注解块的行块阵列。
  • -split '\r?\ngo\r?\n'然后通过单词go前后加一个换行符来进一步分割该数组。

请注意,-split在默认情况下是大小写不敏感的,因此您不必担心GO这样的大小写变化。
(You可以使用别名-isplit来使不区分大小写的行为更加明确;类似地,
-csplit可用于 * 区分大小写 * 的匹配。)

  • -notmatch '^\s*$'从结果数组中过滤出空白/空元素,并通过管道发送过滤后的数组(|)。
  • 然后,ForEach-Object cmdlet通过自动变量$_对每个数组元素(现在包含一个单独的SQL命令)进行操作,该变量始终表示手头的输入对象。
mpbci0fu

mpbci0fu2#

标记为最佳答案的解决方案的简化版本,在此修改以删除PS注解块:

(get-content .\myscript.ps1 -raw) -replace "(?s)<#.+?#>",'' > myscript_Clean.ps1

不确定为什么GO语句会在这里发生干扰。应用到SQL注解块,应该会这样做:

(get-content .\myscript.sql -raw) -replace "(?s)/\*.+?*\/",'' > myscript_Clean.sql
sd2nnvve

sd2nnvve3#

也许你可以在/*上拆分并加入得到的数组,然后在*/上拆分并加入得到的数组。
使用``rn(回车、换行符)分隔符可以更容易地读取连接

相关问题