CSV仅包含文件中的最后一个条目

时间:2019-07-17 16:09:49

标签: regex powershell parsing

CSV文件仅包含最后一次正则表达式匹配的部分条目。

我使用了ISE调试器,可以验证它是否找到匹配项。

$h = @{}
$a = @()
Get-ChildItem C:\Users\speterson\Documents\script\*.kiy | foreach {
    Get-Content $_ | foreach {
        if ($_ -match 'IF Ingroup\s+\(\s+\"(..+?)\"\s+\)') {
            $h.Group = $matches[1]          
        }
        if ($_ -match 'use\s+([A-Za-z]):"(\\\\..*?\\..*)\"'))  {
            $h.DriveLetter = $matches[1].ToUpper()
            $h.Path = $matches[2]
        }
    }

    $a += New-Object PSCustomObject -Property $h
}
$a | Export-Csv c:\temp\Whatever.csv -NoTypeInfo

输入文件如下所示,但是其中有1000多个行:

IF Ingroup ( "RPC3WIA01NT" )
        use v: /del 
ENDIF   
IF Ingroup ( "JWA03KRONOSGLOBAL" )
        use v:"\\$homesrvr\$dept"
ENDIF    
IF Ingroup ( "P-USERS" )
        use p:'\\PServer\PDRIVE 
ENDIF

CSV文件仅显示:

GROUP    
P-USERS

我想用/del忽略驱动器号。

我正在尝试获取显示的CSV文件

Group                Drive          Path
JWA03KRONOSGLOBAL    V              \\$homesrvr\$dept
P-USERS              P              \\PServer\PDRIVE

1 个答案:

答案 0 :(得分:0)

您的代码有两个循环,一个循环嵌套在另一个循环中。外循环处理Get-ChildItem调用中的每个文件。内部循环处理外部循环的当前文件的内容。但是,由于要在内部循环完成后 创建对象,所以只能从每个已处理文件中获取最后一个结果。将对象创建移入内部循环以从所有文件中获取所有结果。

我还建议不要重用哈希表。重用对象始终会带来使数据遗留在不需要的地方的风险。散列表的创建是如此便宜,以至于冒这个风险永远都不值得。

最重要的是,您对文件内容的处理存在缺陷,因为内部循环一次只处理一行内容,但是您的两个条件都在不同的行上匹配并且没有相互链接。如果您每次迭代都创建一个新对象,则会给您不正确的结果。整体读取文件,然后将Select-String与多行正则表达式一起使用以提取所需的信息。

要避免的另一件事是在循环中附加到数组(这是一个很慢的操作,因为它涉及重新创建数组并一遍又一遍地复制元素)。由于您使用的是ForEach-Object,因此可以直接通过管道传输到Export-Csv

类似的事情应该起作用:

$re = 'IF Ingroup\s+\(\s+"(.+?)"\s+\)\s+' +
      "use\s+([a-z]):\s*[`"'](\\\\[^`"'\s]+)"

Get-ChildItem 'C:\Users\speterson\Documents\script\*.kiy' | ForEach-Object {
    Get-Content $_.FullName |
        Out-String |
        Select-String $re -AllMatches |
        Select-Object -Expand Matches |
        ForEach-Object {
            New-Object -Type PSObject -Property @{
                'Group'       = $_.Groups[1].Value
                'DriveLetter' = $_.Groups[2].Value
                'Path'        = $_.Groups[3].Value
            }
        }
} | Export-Csv 'C:\path\to\output.csv' -NoType