如何使用powershell select-string -Allmatch选择多个列并展开属性?

时间:2014-05-15 16:27:03

标签: powershell select-string

我正在搜索一组文本文件(* .sql),发现以9开头的8位数字。文件中可能有多个这些数字的实例以及每个数字的多个实例文件中的行。我只希望输出显示每个文件中每个8位数字的唯一出现。这就是我到目前为止所做的:

Select-String "9[0-9]{8}" "*.sql" -AllMatches | Select-Object FileName, @{N="Value";E={ $_.matches |  %{$_.groups[0].value}}} | Select-Object  -unique FileName,Value  

我的输出看起来像这样:

FileName                       Value
--------                       -----

File1.sql                      907520714
File1.sql                      {907500507, 907520700, 907520701, 907520703...} 
File1.sql                      {907520725, 907520727, 907520728, 907520729} 
File1.sql                      990140600
File2.sql                      990319161
File2.sql                      {990603919, 990603925, 990603926} 
File2.sql                      {991100103, 991100103}
File2.sql                      {990700023, 990700504, 990700521, 990740520...} 
File3.sql                      907500044

等...

我想要做的是扩展数组,以便在通过select -unique管道时 实际上我只会得到每个文件中包含的唯一8位数字。

这就是我想要的:

FileName                       Value
--------                       -----

File1.sql                      907520714
File1.sql                      907500507
File1.sql                      907520700
File1.sql                      907520701
File1.sql                      907520703 
File1.sql                      907520725
File1.sql                      907520727
File1.sql                      907520728
File1.sql                      907520729 
File1.sql                      990140600
File2.sql                      990319161
File2.sql                      990603919
File2.sql                      990603925
File2.sql                      990603926 
File2.sql                      991100103
File2.sql                      990700023
File2.sql                      990700504
File2.sql                      990700521
File2.sql                      990740520 
File3.sql                      907500044

等...

我该怎么做?我现在的powershell命令可以改进吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

好吧,大部分时间都在运行你所拥有的东西。我正在针对Select-String找到的所有匹配进行ForEach循环,并按文件名对它们进行分组。然后,对于每个文件,我遍历扩展匹配的组,然后仅为匹配的文本采用唯一值。对于每个值,我输出一个包含文件名称和匹配值的对象。

ForEach($File in Select-String "9[0-9]{8}" "*.sql" -AllMatches | Group FileName){
    $File.group|select -expand matches|Select Value -Unique|%{
        new-object PSObject -property @{
            FileName=$File.Name
            Match=$_.value
        }
    }
}

答案 1 :(得分:0)

我稍微重新格式化了命令,我认为PowerShell简写的简洁性使得查看问题变得更加困难。

Select-String "9[0-9]{8}" "*.sql" -AllMatches | `
    Select-Object FileName, @{N="Value";E={ $_.matches | %{$_.groups[0].value}}} | `
    Select-Object  -unique FileName,Value 

原始命令为Select-String返回的每个MatchInfo生成一个输出行。 MatchInfo表示文本文件的匹配行。我相信当文件中的一行包含多个匹配值时,您将获得一组值。

我修改了它以澄清我们在每个MatchInfo中为每个RegexMatch想要一个输出对象,也就是说每个匹配值有一个输出对象。

Select-String "9[0-9]{8}" "*.sql" -AllMatches | `
    Foreach-Object { 
        # $_ is MatchInfo for each matching line in file
        $fileName = $_.FileName 
        $_.Matches | Foreach-Object { 
            # $_ is RegexMatch for each match in line
            $_ | Select-Object -Property @{N="FileName";E={$fileName} },Value
        } 
    } | Select-Object  -unique FileName,Value