对匹配组使用“ notin”

时间:2019-07-29 18:40:18

标签: regex powershell

使用powershell,我试图确定未从任何其他脚本中调用目录中的哪些perl脚本。在我的选择字符串中,我将匹配项进行分组,因为我使用了一些其他逻辑来过滤掉注释行的结果,以及一堆我想排除的其他情况(为简单起见,我将其排除在下面的代码中) 。我的主要问题是在“ -notin”部分。

如果我从选择字符串中删除分组并且仅匹配文件名本身,那么我可以使它工作。这样就行了。

$searchlocation = "C:\Temp\"
$allresults = Select-String -Path "$searchlocation*.pl" -Pattern '\w+\.pl'
$allperlfiles = Get-Childitem -Path "$searchlocation*.pl"

$allperlfiles | foreach-object -process{
    $_ | where {$_.name -notin $allresults.matches.value}  | Select -expandproperty name | Write-Host
}

但是,我无法执行以下操作。与此之间的唯一区别是“ -Pattern”的值和“ -notin”之后的值。我不确定如何将“ notin”与匹配组一起使用。

$searchlocation = "C:\Temp\"
$allresults = Select-String -Path "$searchlocation*.pl" -Pattern '(.*?)(\w+\.pl)'
$allperlfiles = Get-Childitem -Path "$searchlocation*.pl"

$allperlfiles | foreach-object -process{
    $_ | where {$_.name -notin $allresults.matches.groups[2].value}  | Select -expandproperty name | Write-Host}

在较高级别,代码应在目录中的所有perl脚本中搜索执行任何其他perl脚本的任何行。有了它,我现在有了$ allresults,它基本上为我提供了从其他文件调用的所有perl脚本的列表。为了得到相反的结果(未从任何其他文件调用的文件),我得到了目录中所有perl脚本的列表,循环浏览这些脚本并列出DONT在$ allresults中显示的那些脚本。

1 个答案:

答案 0 :(得分:2)

选择分组时,需要使用Select语句或循环迭代,否则,您将仅从第N个匹配项中选择值。

IE(如果您的$Allresults对象包含

  

File.pl,File 2.pl,File 3.pl

然后$allresults.Matches.Groups[2].value 仅返回 File2.pl

相反,您需要选择这些值!

$allresults | select  @{N="Match";E={ $($_.Matches.Groups[2].value) } }

哪个会返回:

Match                         
-----  
File1.pl
File2.pl
File3.pl

在您的特定示例中,每个匹配项都有三个子项,结果将完全是连续的,因此您将“匹配项1,组1”称为groups[0],而“匹配项2,组1”则称为groups[3]

这意味着您关心的匹配项(分组为2的匹配项)在集合{2,5,8,11,...等}中包含的数组值中,或可以描述为{{1} }其中(N*3-1)是匹配项的编号。因此,对于匹配N = 1 = (1*3)-1;而对于比赛[2] = 13 = (13*3)-1

您可以使用循环来遍历它们以检查:

[38]

我注意到您花了一些时间避免收集数据的循环,但是随后偶然地似乎误以为使用一个来匹配数据。

for($i=0; $i -le ($allresults.Matches.groups.count-1); $i++){ "Group[$i] = ""$($allresults.Matches.Groups[$i].value)""" } 和其他比较由Not-Inselect子句使用时不需要循环结构,如果不循环则更快,因此您可以放弃{{1} },只需使用简单的whereForeach-object)就可以循环并获得更好的处理效果。

Where

现在,应该更快,并且要维护的代码更简单,但是,正如您可能已经注意到的,它现在仍有一些冗余你没有循环。

当您将所有内容通过管道传递给Select时,它可以完成where的工作,此外,您只希望在此处匹配NAME属性,因此您可以仅通过管道传递名称来放弃最后的选择该文件放在首位,或者您可以放弃该位置,然后完全选择所需的文件。

我认为前者要简单得多,而后者对于在循环中实际使用我们尚不知道的其他值做些有用的事情很有用。

最后,写主机可能是多余的,因为任何对象输出都会回显到控制台。

这里是合并不需要的循环并删除与所需信息输出相关的冗余的版本。

?