使用带有 where-object 的数组从 csv 中过滤多个字符串

Using arrays with where-object to filter multiple strings out of a csv

我正在尝试从 csv 中过滤出包含数组中任何值的行。

使用此 post 作为参考: Use -notlike to filter out multiple strings in PowerShell

我设法让它使用这种格式:

Import-Csv "$LocalPath\Stripped1Acct$abbrMonth$Year.csv" | 
    where {$_."SubmitterName" -notlike "*${Report2a}*" 
      -and $_."SubmitterName" -notlike "*${Report2b}*" 
      -and $_."SubmitterName" -notlike "*${Report2c}*"} |
    Export-Csv "$LocalPath\Stripped2Acct$abbrMonth$Year.csv" -NoTypeInformation

最终我打算重写脚本,以便从最终用户生成的文本文件中提取排除列表。为此,我必须让它访问数组中的值。我尝试使用以下语法来做到这一点,但它没有按预期工作:

Import-Csv "$LocalPath\Stripped1Acct$abbrMonth$Year.csv" | 
    where {$_."SubmitterName" -notlike "*${Report2[0]}*" 
      -and $_."SubmitterName" -notlike "*${Report2[1]}*" 
      -and $_."SubmitterName" -notlike "*${Report2[2]}*"} |
    Export-Csv "$LocalPath\Stripped2Acct$abbrMonth$Year.csv" -NoTypeInformation

我感觉这只是一个语法问题,但在研究它太久之后,我 运行 没主意了。 我感觉这是一个语法问题

这是语法问题。 ${Name} 语法主要用于包含奇数字符的名称,如 ${A ~*Strange*~ Variable Name}。虽然它不是表达式,所以你不能用大括号内的 [0] 索引它;这将被视为变量名称的文字部分。

相反,您可以使用子表达式 $(...) 来执行此操作:

"*$($Report2[0])*"

作为替代方法,我可能会将您的整个数组转换为单个正则表达式,然后使用 -match(或 -notmatch)运算符:

$regex = $Report2.ForEach({ [RegEx]::Escape($_) }) -join '|'

Import-Csv "$LocalPath\Stripped1Acct$abbrMonth$Year.csv" | 
    where {$_."SubmitterName" -notmatch $regex} |
    Export-Csv "$LocalPath\Stripped2Acct$abbrMonth$Year.csv" -NoTypeInformation

这采用 $Report2 数组,然后构建一个具有相同值的数组,但针对正则表达式进行了转义(以便按字面匹配任何特殊字符),然后构建一个如下所示的正则表达式:

Item1|Item2|Item3

在 RegEx 中,管道是交替的,因此它会查找 Item1 Item2 等的匹配项。Regex 会在字符串,因此它不需要像 -like 那样需要通配符。

因此,构建为预先包含数组中的所有项目后,您可以使用 -notmatch 来实现相同的目的,而不必对一堆索引进行硬编码。

你也可以像这样使用包含

简短版本

[string[]]$listexludevalue=Get-Content "C:\temp\exludevalue.txt"
Import-Csv "$LocalPath\Stripped1Acct$abbrMonth$Year.csv" | %{$valcontain=$true; $col=$_.Owner; $listexludevalue.ForEach({$valcontain=$valcontain -and !$col.Contains($valuetotest)}); if ($valcontain) {$_} } | Export-Csv "$LocalPath\Stripped2Acct$abbrMonth$Year.csv" -NoTypeInformation

详细版本:

$listexludevalue=Get-Content "C:\temp\exludevalue.txt"

Import-Csv "$LocalPath\Stripped1Acct$abbrMonth$Year.csv" | 
% {

    $valcontain=$true

    foreach ($valuetotest in $listexludevalue) {$valcontain=$valcontain -and !$_.SubmitterName.Contains($valuetotest)}

    if ($valcontain) {$_}

   } | Export-Csv "$LocalPath\Stripped2Acct$abbrMonth$Year.csv" -NoTypeInformation