首页 > 解决方案 > 使用 Powershell 注释掉文本文件中的“代码块”?

问题描述

我正在尝试在大量文件中注释掉一些代码

这些文件都包含以下内容:

    stage('inrichting'){
        steps{
              build job: 'SOMENAME', parameters: param
              build job: 'SOMEOTHERNAME', parameters: param
              echo 'TEXT'
        }
    }

里面的东西steps{ }是可变的,但总是存在于 0..N 'echo' 和 0..N 'build job'

我需要一个像这样的输出:

    //stage('inrichting'){
    //   steps{
    //        build job: 'SOMENAME', parameters: param
    //        build job: 'SOMEOTHERNAME', parameters: param
    //        echo 'TEXT'
    //  }
    //}

有什么好的方法可以用 PowerShell 做到这一点吗?我用 pattern.replace 尝试了一些东西,但没有走得太远。

$list = Get-ChildItem -Path 'C:\Program Files (x86)\Jenkins\jobs' -Filter config.xml -Recurse -ErrorAction SilentlyContinue -Force | % { $_.fullname };
foreach ($item in $list) {
...
}

标签: regexpowershell

解决方案


这有点棘手,因为您试图找到整个部分,然后将注释标记添加到其中的所有行。如果您的结构允许,我可能会编写一个临时解析器switch -regex(计算大括号可能会使事情变得更健壮,但对于所有情况也更难正确)。如果代码足够规则,您也许可以将其简化为以下内容:

stage('inrichting'){
    steps{
        ... some amount of lines that don't contain braces
    }
}

然后我们可以检查是否出现在开头的两个固定行,最后是两个带有右括号的行:

 foreach ($file in $list) {
    # lines of the file
    $lines = Get-Content $file
    # line numbers to comment out
    $linesToComment = @()
    # line number of the current block to comment
    $currentStart = -1
    # the number of closing braces on single lines we've encountered for the current block
    $closingBraces = 0

    for ($l = 0; $l -le $lines.Count; $l++) {
        switch -regex ($lines[$l]) {
            '^\s*stage\('inrichting'\)\{' {
                # found the first line we're looking for
                $currentStart = $l
            }
            '^\s*steps\{' {
                # found the second line, it may not belong to the same block, so reset if needed
                if ($l -ne $currentStart + 1) { $currentStart = -1 }
            }
            '^\s*}' {
                # only count braces if we're at the correct point
                if ($currentStart -ne -1) { $closingBraces++ }
                if ($closingBraces -eq 2) {
                # we've reached the end, add the range to the lines to comment out
                $linesToComment += $currentStart..$l
                $currentStart = -1
                $closingBraces = 0
                }
            }
        }
    }

    $commentedLines = 0..($lines.Count-1) | % {
      if ($linesToComment -contains $_) {
        '//' + $lines[$_]
      } else {
        $lines[$_]
      }
    } | Set-Content $file

 }

未经测试,但总体思路可能有效。

更新:已修复并经过测试


推荐阅读