【问题标题】:PowerShell remove all comments from a scriptPowerShell 删除脚本中的所有注释
【发布时间】:2020-07-14 17:51:07
【问题描述】:

我正在寻找一种从文件中删除所有 cmets 的方法。 cmets 有多种方法,但我只对简单的# 形式的 cmets 感兴趣。原因是我只将<# #> 用于函数内.SYNOPSIS,这是函数代码,而不仅仅是注释,所以我想保留这些)。

编辑:我已经使用下面的有用答案更新了这个问题。

所以我只需要几个场景:

a) 在行首使用 # 的整行 cmets(或者之前可能带有空格。即 ^\s*# 的正则表达式似乎有效。

b) 在行首有一些代码,然后在行尾有一个命令。 我想避免剥离具有例如Write-Host "#####" 但我认为这已包含在我拥有的代码中。

我能够通过拆分删除行尾 cmets,因为我无法弄清楚如何使用正则表达式来做到这一点,有人知道用正则表达式实现这一目标的方法吗?

拆分并不理想,因为一行上的<# 会被-split 删除,但我已经通过拆分" #" 解决了这个问题。这并不完美,但可能已经足够好了——也许存在更可靠的正则表达式方式?

当我对我的 7,000 行长的脚本执行以下操作时,它可以工作(!)并剥离大量的 cmets,但是,输出文件的大小几乎翻了一番(!?)从 400kb 到大约 700kb。有谁明白为什么会发生这种情况以及如何防止这种情况(它与 BOM 或 Unicode 或类似的东西有关吗?Out-File 似乎真的使文件大小膨胀!)

$x = Get-Content ".\myscript.ps1"   # $x is an array, not a string
$out = ".\myscript.ps1"
$x = $x -split "[\r\n]+"               # Remove all consecutive line-breaks, in any format '-split "\r?\n|\r"' would just do line by line
$x = $x | ? { $_ -notmatch "^\s*$" }   # Remove empty lines
$x = $x | ? { $_ -notmatch "^\s*#" }   # Remove all lines starting with ; including with whitespace before
$x = $x | % { ($_ -split " #")[0] }    # Remove end of line comments
$x = ($x -replace $regex).Trim()       # Remove whitespace only at start and end of line
$x | Out-File $out
# $x | more

【问题讨论】:

  • 在 Windows PowerShell 中,我相信 out-file 默认编码为 UTF16-LE,可能使用 BOM。您可以尝试Set-Content,它默认为 ANSI 编码。对于任一命令,您都可以使用-Encoding 参数。 UTF8 编码将具有带有这些命令的 BOM。
  • 很高兴知道谢谢,一旦我使用Set-Content,文件大小就降到了 220k 而不是 700k。我从来没有想过使用这些不同的编码以及为什么有些如此臃肿......谢谢。

标签: regex powershell comments


【解决方案1】:

老实说,识别和处理所有 cmets 的最佳方法是使用 PowerShell 的语言解析器或 Ast 类之一。抱歉,我不知道哪个 Ast 包含 cmets;所以这是一种更丑陋的方式,可以过滤掉块和行 cmets。

$code = Get-Content file.txt -Raw
$comments = [System.Management.Automation.PSParser]::Tokenize($code,[ref]$null) |
    Where Type -eq 'Comment' | Select -Expand Content
$regex = ( $comments |% { [regex]::Escape($_) } ) -join '|'

# Output to remove all empty lines
$code -replace $regex -split '\r?\n' -notmatch '^\s*$'

# Output that Removes only Beginning and Ending Blank Lines
($code -replace $regex).Trim()

【讨论】:

  • 这是惊人的。和你的回答一样,它比我知道的存在的东西要高出一个层次。 Ast 课程对我来说是某种“黑魔法”。我看到您在这里的方法绝对是全面解决方案的最佳方法。我认为我目前的需求有点简单,所以我更新了我的主要问题(并使用了你删除空行和行修剪开始/结束,这非常有用,谢谢),如果你对修改点有一些解决方案在那里,将不胜感激。
【解决方案2】:

与您的示例相反:仅发出不匹配的行:

## Output to console
Get-Content .\file.ps1 | Where-Object { $_ -notmatch '#' }

## Output to file
Get-Content .\file.ps1 | Where-Object { $_ -notmatch '#' } | Out-file .\newfile.ps1 -Append

【讨论】:

  • 理想,我已经以您在此处的回答为基础更新了我的问题,它引导我进行了一些其他改进,也许您对如何解决有想法?
猜你喜欢
  • 2019-07-04
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多