PowerShell:列出 CSV 文件行,其中第 3 列和最后一列之间的至少一个值等于“0”或“1”

PowerShell: list CSV file rows where at least one value between the 3rd and last column is equal to "0" or "1"

在我的 PowerShell 脚本中,我正在处理一个 CSV 文件,它看起来像这样(有许多行和列可以变化,但总是至少有 headers 和前 2 列):

OS;IP;user0;user1;user3
Windows;10.0.0.1;;;
Linux;hostname2;0;;1
Linux;10.0.0.3;;0;0
Linux;hostname4;;;
Windows;hostname5;1;1;1

我基本上在第一列列出服务器,在第一行列出用户 (CSV header)。这表示服务器的用户 "access granting" 矩阵("give access" 为 1,"remove access" 为 0,"don't change" 为空)。

我正在寻找一种方法来仅提取在第 3 列和最后一列之间(包括)包含等于“1”或“0”的值的行。 (= 最终获得应更改访问权限的服务器列表)

以上面的例子为例,我只想返回以下几行:

Linux;hostname2;0;;1
Linux;10.0.0.3;;0;0
Windows;hostname5;1;1;1

有什么提示可以实现吗?或者相反(得到没有任何 0 或 1 的那些)? 即使这意味着使用 "Get-Content" 而不是 "Import-CSV"。我不关心第一 (headers) 行;我知道如何排除它。

谢谢!

--- 最终解决方案,感谢@Tomalak 的回答:

$AccessMatrix = Import-CSV $CSVfile -delimiter ';'
$columns = $AccessMatrix | Get-Member -MemberType NoteProperty | Select-Object -Skip 2 -ExpandProperty Name
$AccessMatrix = $AccessMatrix | ForEach-Object {
    $row = $_
    foreach ($col in $columns) {
        if ($row.$col.trim() -eq "1" -OR $row.$col.trim() -eq "0") {
            $row         # this pushes the $row onto the pipeline
            break
        }
    }
}

以下使用Get-Member到select前两列之后的所有列的名称。

然后,使用 ForEach-Object,我们可以只输出那些在任何这些列中有值的行。

$data = ConvertFrom-Csv "OS;IP;user0;user1;user3
Windows;10.0.0.1;;;
Linux;hostname2;0;;1
Linux;10.0.0.3;;0;0
Linux;hostname4;;;
Windows;hostname5;1;1;1" -Delimiter ";"

$columns = $data | Get-Member -MemberType NoteProperty | Select-Object -Skip 2 -ExpandProperty Name

$data | ForEach-Object {
    $row = $_
    foreach ($col in $columns) {
        if ($row.$col -ne "") {
            $row         # this pushes the $row onto the pipeline
            break
        }
    }
}

break 语句停止执行内部 foreach 循环,因为一旦找到具有任何值的第一列就没有进一步检查的意义。

这相当于上面的,如果你更喜欢Where-Object:

$data | Where-Object {
    $row = $_
    foreach ($col in $columns) {
        if ($row.$col -ne "") {
            return $true
        }
    }
}