我正在对某些PowerShell数据集进行规范化,一个处理步骤是将所有变量替换为X,并将所有字符串文字替换为Y,以便我可以检测和删除几乎重复的重复项。
但是,我注意到对于规范化后的许多脚本,整个脚本可以归结为很多Y和一些X,几乎没有其他任何代码。这不是我所期望的,因为脚本中只有少数变量和字符串文字。
要查找所有字符串文字,我使用了以下命令:
$Strings = $AST.FindAll({$args[0] -is System.Management.Automation.Language.StringConstantExpressionAst]}, $true)
为了解决此问题,我使用了ShowPSAst(PowerShell AST可视化工具)来可视化一个示例脚本,其中上述问题很明显。
原始脚本如下所示:
Describe "Files" -Tag OSX,Linux {
It "is utf-8 encoded" {
$true | Should Be $false
}
It "uses Unix-style line endings" {
$true | Should Be $false
}
It "has a shebang" {
$true | Should Be $false
}
}
Describe "Placeholder for Nano tests" -Tag Nano {
}
规范化后,我得到以下内容:
Y Y -Tag Y,Y {
Y Y {
X | Y Y X
}
Y Y {
X | Y Y X
}
Y Y {
X | Y Y X
}
}
Y Y -Tag Y {
}
上面脚本的AST可视化摘录:
请注意,图像右面板中突出显示的部分与左面板中的AST节点相对应,然后AST节点CommandAST
具有许多子StringConstantExpressionAst
节点。查看这些AST节点,就可以理解为什么我的规范版本中有那么多Y。但是,令我感到困惑的是,为什么突出显示的代码中几乎所有的单独标记都被视为StringContantExpressionAst
。我希望只"Placeholder for Nano tests"
将其视为String Literal。
确切地说,我希望
Describe "Placeholder for Nano tests" -Tag Nano
转化为
Describe Y -Tag Nano
而不是
Y Y -Tag Y
I don't really use PowerShell on my own and don't know its intricacies, so I apologize if I'm missing something basic and I am thankful in advance for any help in understanding this PowerShell behavior.
PowerShell is an interpreted language, which means it doesn't attach a meaning to some parts of your code until you run it. In your case, it doesn't know that the word "Describe" is referring to the Describe function in the Pester module (which might not even be imported into your session yet), and it could equally mean an external program called "Describe.exe" for example.
All the parser does is make a note of the name of the command as a StringConstantExpressionAst
, and it's up to the runtime logic to look for something to run that has that name.
如果仔细查看AST,您会发现“ Describe”令牌的StringConstantType
属性为,BareWord
而"my tests"
字符串的值为DoubleQuoted
。如果只想对“文字字符串”进行处理,则可以将该StringConstantType
属性用作过滤器。
$Strings = $AST.FindAll(
{
( $args[0] -is [System.Management.Automation.Language.StringConstantExpressionAst] ) -and
( $args[0].StringConstantType -ne "BareWord" )
},
$true
)
除了那么你可能会等东西错过未加引号的字符串:
Describe Files -Tag OSX,Linux {
因此,另一个(更好的?)选项可能是忽略任何CommandAst节点中的第一个子元素。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句