Powershell,如何捕获SelectString的参数并包含匹配的输出



感谢@mktlement0的帮助,在Powershell搜索目录中为文本匹配的代码文件提供了答案,并输入了一个txt文件。

下面的Powershell可以很好地查找源代码文件夹中数据库字段名的长列表。

$inputFile = 'C:DataColumnsNames.txt'
$outputFile = 'C:DataColumnsUsages.txt'
Get-ChildItem C:ProjectFolder -Filter *.cs -Recurse -Force -ea SilentlyContinue |
Select-String -Pattern (Get-Content $inputFile) | 
Select-Object Path, LineNumber, line | 
Export-csv $outputfile

但是,许多行源代码都有多个匹配项,尤其是一行中有许多字段名的ADO.NET SQL语句。如果匹配输出中包含字段名称参数,则结果将更直接有用,而不需要额外的处理,例如将所有内容与原始字段名称列表对齐。例如,如果存在源极线"0";BatchId=新Id";它将与字段名称列表项"相匹配;BatchId";。有没有一种简单的方法可以在输出中包括";BatchId";以及";BatchId=新Id"?

用火柴对象玩,但它似乎没有信息。也尝试了类似这里的Pipeline变量,但X为空。

$inputFile = 'C:DataColumnsNames.txt'
$outputFile = 'C:DataColumnsUsages.txt'
Get-ChildItem C:ProjectFolder -Filter *.cs -Recurse -Force -ea SilentlyContinue |
Select-String -Pattern (Get-Content $inputFile -PipelineVariable x) | 
Select-Object $x, Path, LineNumber, line | 
Export-csv $outputile

谢谢。

Select-String输出的Microsoft.PowerShell.Commands.MatchInfo实例具有Pattern属性,该属性反映传递给-Pattern的(潜在)阵列中的特定模式,该阵列在给定行上匹配

警告是,如果多个模式匹配,则.Pattern仅报告匹配的模式中的模式,该模式在-Pattern参数中首先列出。

这里有一个简单的例子,使用字符串数组模拟文件中的行作为输入:

'A fool and',
'his barn',
'are soon parted.',
'foo and bar on the same line' | 
Select-String -Pattern ('bar', 'foo') | 
Select-Object  Line, LineNumber, Pattern

以上收益率:

Line                         LineNumber Pattern
----                         ---------- -------
A fool and                            1 foo
his barn                              2 bar
foo and bar on the same line          4 bar

注意'bar'是如何列为最后一行的Pattern值的,即使'foo'首先出现在输入行中,因为'bar'pattern array'foo'之前。


为了反映Pattern属性中首先出现在输入行上的实际模式,还需要做更多的工作:

  • 使用交替(|)将您的模式数组公式化为单个正则表达式,作为一个整体封装在捕获组中((...)),例如'(bar|foo)')

    • 注意:下面使用的表达式'({0})' -f ('bar', 'foo' -join '|')根据数组动态构造此正则表达式(此处为数组文字'bar', 'foo',但您可以替换任何数组变量,甚至(Get-Content $inputFile));如果您想将输入模式视为文字,并且它们恰好包含regex元字符(如.),则需要首先使用[regex]::Escape()对其进行转义
  • 使用计算的属性定义自定义Pattern属性,该属性报告捕获组的值,该值是每个输入行上遇到的值中的第一个:

'A fool and',
'his barn',
'are soon parted.',
'foo and bar on the same line' | 
Select-String -AllMatches -Pattern ('({0})' -f ('bar', 'foo' -join '|')) | 
Select-Object Line, LineNumber, 
@{ n='Pattern'; e={ $_.Matches[0].Groups[1].Value } }

这产生(缩写为只显示最后一场比赛):

Line                         LineNumber Pattern
----                         ---------- -------
...
foo and bar on the same line          4 foo

现在,'foo'被适当地报告为匹配模式。


报告每行上发现的所有模式

  • 开关-AllMatches需要告诉Select-String在每行上查找所有匹配项,这些匹配项在MatchInfo输出对象的.Matches集合中表示。

  • 然后必须枚举.Matches集合(通过.ForEach()集合方法),以从每个匹配中提取捕获组值。

'A fool and',
'his barn',
'are soon parted.',
'foo and bar on the same line' | 
Select-String -AllMatches -Pattern ('({0})' -f ('bar', 'foo' -join '|')) | 
Select-Object Line, LineNumber, 
@{ n='Pattern'; e={ $_.Matches.ForEach({ $_.Groups[1].Value }) } }

这产生(缩写为只显示最后一场比赛):

Line                         LineNumber Pattern
----                         ---------- -------
...
foo and bar on the same line          4 {foo, bar}

请注意'foo''bar'现在是如何在Pattern中按行中遇到的顺序报告的。

@mktlement0中的可靠信息和示例足以为我研究和理解Powershell、对象管道和计算属性指明正确的方向。

我终于实现了将表和字段名列表交叉引用到C#代码库的目标。输入文件只是用管道分隔的表名和字段名。(我遇到的一个小故障是在分割中没有使用管道,这是一个视觉错误,需要一段时间才能最终看到,所以请检查一下)。输出是表名、字段名、代码文件名、行号和实际行。这并不完美,但比几百块田地的手工作业要好得多!现在,数据映射和转换项目有可能实现进一步的自动化。考虑过使用C#实用程序编程,但这可能需要同样长的时间来计算和实现,而且比工作的Powershell要麻烦得多。

在这一点上,对我来说关键是";工作"!我第一次深入了解Powershell的深奥世界。我的解决方案的关键点是使用计算的属性来获得输出中的表和字段名,实现表达式可以在某些地方使用,比如构建模式,并且管道在每个命令之后只传递特定的对象(也许这对视图来说太受限了,但它比我以前的要好)。

希望这对将来的人有所帮助。我找不到任何接近的例子来克服困难,所以问了我有史以来第一个堆叠式的问题。

$inputFile = "C:input.txt"
$outputFile = "C:output.csv"
$results = Get-Content $inputfile
foreach ($i in $results) {
Get-ChildItem -Path "C:ProjectFolder"  -Filter *.cs  -Recurse -ErrorAction SilentlyContinue -Force |
Select-String -Pattern  $i.Split('|')[1] |
Select-Object   @{ n='Pattern'; e={ $i.Split('|')[0], $i.Split('|')[1]  -join '|'} },  Filename, LineNumber, line |
Export-Csv $outputFile -Append}

相关内容

  • 没有找到相关文章

最新更新