使用 PowerShell 根据配置文件中的排除条件排除 CSV 文件中的记录

Exclude records in CSV file based on exclusion criteria in Config file using PowerShell

我正在处理的用例是从命令提示符中提取详细信息服务列表运行 用于特定应用程序,例如 Tableau 等。输出通常采用以下格式

Tableau 服务中的文件内容

'Service 0' is running
'Service 1' is running
'Service 2' is running
'Service 3' is running
'Service 4' is running
'Test Service 5' is stopped
'SAML Service 6' is stopped
'Database Service 7' is stopped
'Tableau Service 8' is stopped
'Service 9' is running
'Service 10' is running
'Service 11' is running
'Service 12' is stopped
'Service 13' is running
'Service 14' is running
'Service 15' is stopped

最终结果应该给出已经停止的服务列表

Service 12
Service 15

脚本

 #EXTRACT THE CONTENTS FROM THE TABLEAU SERVICES
    $content = Get-Content 'C:\Tableau Services\TableauServices.txt'
    $content.replace("`t", "").Replace(" is ",",").replace(".","").Replace("'","").Trim() | select -Skip 2 | Out-File 'C:\Tableau Services\TableauServices.csv'
    
    $iRunningNumber=1
    #Extract Services which have Stopped
    Write-Host ("The List of Services that have stopped are as below: - ")
    Import-CSV -Path 'C:\Tableau Services\TableauServices.csv' `
                -delimiter ”,” `
                -Header ServiceName, Status | 
                    Where-Object {$_.ServiceName -notlike "*Test Service 5*" -AND $_.ServiceName - notlike "*SAML Service 6*" -AND $_.ServiceName -notlike "*Database Service 7*" -AND $_.ServiceName -notlike "*Tableau Service 8*"} | 
                     Select-Object ServiceName, Status |
                        Where-Object {$_.Status -match "Stopped*"} | 
                            ForEach-Object {"$($iRunningNumber).) $($_.ServiceName)"; $iRunningNumber++}
                    

目前,要排除的服务是硬编码在代码中的。我想从配置文件中提取这些条件,然后搜索并从最终列表中排除。

我有另一个文件,其中包含要忽略的服务列表,如下所示:- SearchFile.txt

Test Service 5
SAML Service 6
Database Service 7
Tableau Service 8

我已经尝试了我所知道的一切,但仍然没有解决办法。请求你的帮助

如果您使用的是纯文本文件并且它们包含您发布的内容,您可以执行以下操作:

$Ignore = (Get-Content SearchFile.txt | Foreach-Object {
    [regex]::Escape($_)}) -join '|'
(Get-Content TableauServices.txt) -notmatch $Ignore -match 'Stopped' -replace "^.*?'([^']+)'.*$",''

解释:

由于 -match-notmatch 使用正则表达式匹配,您将需要创建一个正则表达式友好的字符串。正则表达式中的 OR 等价于 |。对于您想忽略的项目,我们可以使用 | 加入它们。 [regex]::Escape() 的要点是转义搜索字符串中的任何特殊正则表达式字符。转义告诉正则表达式逐字匹配。

^ 匹配字符串的开头。 .*? 尽可能少的字符,直到匹配下一个字符(' 在我们的例子中)。 '' 的字面匹配。 [^'] 是一个否定 (^) 字符 class ([]) 以匹配任何不是 ' 的字符。 + 匹配前一个或多个字符。 .* 贪婪地匹配零个或多个字符。 $ 是字符串的结尾。

因为 -replace 有两部分,第一部分匹配字符串,第二部分作为替换。由于我们使用 () 对匹配项进行分组,因此成为捕获组(组 1 因为它是 () 的第一组)。您可以使用语法 '$CaptureGroup' 在替换字符串中引用捕获组,在本例中为 ''

一些事情。

  1. 您无需创建 csv 文件即可立即将其导回。您可以使用 ConvertFrom-Csv

    直接将 csv 数据转换为对象
  2. 使用 Get-Content 时的 -Raw 参数比未指定时提供更好的性能。但是,它会将您的文件作为单个字符串加载。出于这个原因,我将它与 TableauServices 一起使用,因为我们将它编辑为单个字符串并在 $ExcludeServicesConfig 中省略了它,因为我们需要数据作为后续调用的数组 $ExcludeServicesConfig.Contains($Item.ServiceName)

  3. 我重构了您的代码以使用 Foreach 循环而不是将所有内容都塞入管道中。如果您以后遇到问题,这将使调试变得更加容易。

最终,关键的修改是检查每个项目是否属于排除列表的一部分并做出相应的反应。

这是代码。

.

#EXTRACT THE CONTENTS FROM THE TABLEAU SERVICES
$content = Get-Content 'C:\Tableau Services\TableauServices.txt' -Raw
$ExludeServicesConfig = Get-Content -Path 'SearchFile.txt' 

$obj = $content.replace("`t", "").Replace(" is ", ",").replace(".", "").Replace("'", "").Trim() | 
    ConvertFrom-Csv -Header 'ServiceName', 'Status'
    
$iRunningNumber = 1


#Extract Services which have Stopped
Write-Host ("The List of Services that have stopped are as below: - ")

Foreach ($item in $obj) {
    if ($ExludeServicesConfig.Contains($Item.serviceName)) { Continue }
    if ( $item.Status -eq "Stopped") {
        "$($iRunningNumber).) $($item.ServiceName)"
        $iRunningNumber += 1
    }
}