Powershell,如何捕获 Select-String 的参数并包含匹配的输出 [英] Powershell, how to capture argument(s) of Select-String and include with matched output
问题描述
感谢@mklement0 帮助我们解决了Powershell 搜索目录中的代码文件与文本匹配输入 txt 文件.
Thanks to @mklement0 for the help with getting this far with answer given in Powershell search directory for code files with text matching input a txt file.
下面的 Powershell 非常适合在源代码文件夹中查找一长串数据库字段名称的出现.
The below Powershell works well for finding the occurrences of a long list of database field names in a source code folder.
$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 语句在一行中有很多字段名.如果字段名称参数包含在匹配的输出中,结果将更直接有用,而无需额外的按摩,例如将所有内容与原始字段名称列表对齐.例如,如果有源行BatchId = NewId"它将匹配字段名称列表项BatchId".是否有一种简单的方法可以将BatchId"和BatchId"都包含在输出中?和BatchId = NewId"?
However, many lines of source code have multiple matches, especially ADO.NET SQL statements with a lot of field names on one line. If the field name argument was included with the matching output the results will be more directly useful with less additional massaging such as lining up everything with the original field name list. For example if there is a source line "BatchId = NewId" it will match field name list item "BatchId". Is there an easy way to include in the output both "BatchId" and "BatchId = NewId"?
玩过matches对象,但似乎没有信息.也试过像这里这样的管道变量,但 X 为空.
Played with the matches object but it doesn't seem to have the information. Also tried Pipeline variable like here but X is null.
$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
谢谢.
推荐答案
Microsoft.PowerShell.Commands.MatchInfo
实例,Select-String
输出具有 一个 Pattern
属性,它反映了(潜在的) array 传递给 -Pattern
的模式,这些模式在给定的行上匹配.
The Microsoft.PowerShell.Commands.MatchInfo
instances that Select-String
outputs have a Pattern
property that reflects the specific pattern among the (potential) array of patterns passed to -Pattern
that matched on a given line.
警告是如果多个模式匹配,.Pattern
只报告列出的那些匹配的模式first 其中在-Pattern
参数中.
The caveat is that if multiple patterns match, .Pattern
only reports the pattern among those that matched that is listed first among them in the -Pattern
argument.
这是一个简单的例子,使用一个字符串数组来模拟来自文件的行作为输入:
Here's a simple example, using an array of strings to simulate lines from files as input:
'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'
在模式数组中出现在'foo'
之前.
Note how 'bar'
is listed as the Pattern
value for the last line, even though 'foo'
appeared first in the input line, because 'bar'
comes before 'foo'
in the pattern array.
要在Pattern
属性中反映首先出现在输入行的实际模式,还需要做更多的工作:
To reflect the actual pattern that appears first on the input line in a Pattern
property, more work is needed:
使用 alternation (
|
) 将您的模式数组制定为 单个正则表达式,并作为一个整体包装在 捕获组 ((...)
) - 例如,'(bar|foo)'
)
Formulate your array of patterns as a single regex using alternation (
|
), wrapped as a whole in a capture group ((...)
) - e.g.,'(bar|foo)'
)
- 注意:下面使用的表达式,
'({0})' -f ('bar', 'foo' -join '|')
,动态构造这个正则表达式,来自一个数组(这里的数组字面量'bar', 'foo'
,但你可以替换任何数组变量甚至(Get-Content $inputFile)
);如果您想将输入模式视为 literals 并且它们碰巧包含正则表达式元字符(例如.
),则需要使用[regex]::Escape()
首先.
- Note: The expression used below,
'({0})' -f ('bar', 'foo' -join '|')
, constructs this regex dynamically, from an array (the array literal'bar', 'foo'
here, but you can substitute any array variable or even(Get-Content $inputFile)
); if you want to treat the input patterns as literals and they happen to contain regex metacharacters (such as.
), you'll need to escape them with[regex]::Escape()
first.
使用计算属性定义自定义Pattern
属性,该属性报告捕获组的值,这是每个输入行上遇到的值中的第一个:
Use a calculated property to define a custom Pattern
property that reports the capture group's value, which is the first among the values encountered on each input line:
'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 } }
这产生(缩写为仅显示最后一场比赛):
This yields (abbreviated to show only the last match):
Line LineNumber Pattern
---- ---------- -------
...
foo and bar on the same line 4 foo
现在,'foo'
被正确地报告为匹配模式.
Now, 'foo'
is properly reported as the matching pattern.
要报告在每一行中发现的所有模式:
To report all patterns found on each line:
Switch
-AllMatches
需要告诉Select-String
在每一行查找 all 匹配,用表示>.Matches
MatchInfo
输出对象的集合.
Switch
-AllMatches
is required to tellSelect-String
to find all matches on each line, represented in the.Matches
collection of theMatchInfo
output objects.
然后必须枚举 .Matches
集合(通过 .ForEach()
集合方法)以从每个匹配中提取捕获组值.
The .Matches
collection must then be enumerated (via the .ForEach()
collection method) to extract the capture-group value from each match.
'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 }) } }
这产生(缩写为仅显示最后一场比赛):
This yields (abbreviated to show only the last match):
Line LineNumber Pattern
---- ---------- -------
...
foo and bar on the same line 4 {foo, bar}
注意 'foo'
和 'bar'
现在如何在 Pattern
中按顺序报告遇到就行.
Note how both 'foo'
and 'bar'
are now reported in Pattern
, in the order encountered on the line.
这篇关于Powershell,如何捕获 Select-String 的参数并包含匹配的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!