【问题标题】:How to filter CSV File with PowerShell?如何使用 PowerShell 过滤 CSV 文件?
【发布时间】:2021-09-20 19:36:01
【问题描述】:

我有一个用于备份报告的 CSV 文件,其中有多个列。我只想获得那些从未成功使用特定存储集的客户。

示例输入文件是

Client Name,Save Set Name,Group,Status
a,All,Group1,Failed
a,SQL,Group2,succeeded
b,SQL,Group1,Failed
c,FS,Group1,Failed
d,DBA,Group1,Failed
e,RDM,Group1,Failed
a,ALL,Group2,succeeded
b,SQL,Group3,succeeded
c,SQL,Group4, Failed

输出

Client Name Save Set Name   Status  Group
a   All Failed  Group1
b   SQL Failed  Group1
c   FS  Failed  Group1
d   DBA Failed  Group1
e   RDM Failed  Group1
c   SQL Failed  Group4

预期输出

Client Name,Save Set Name,Group,Status
c,FS,Group1,Failed
d,DBA,Group1,Failed
e,RDM,Group1,Failed
c,SQL,Group4, Failed

在我下面的命令中,我面临的问题是我正在以 Failed 的身份获得在其他组中成功的客户,而我只想要那些具有失败且没有任何成功价值的存储集的客户处于状态。

Get-Content E:\Report\Daily_Failed.csv | 
    ConvertFrom-Csv | 
        Select-Object -Unique * | 
            Group-Object -Property 'Client Name', 'Save Set Name', 'Group' | 
                Where-Object { 0 -eq ($_.Group | Where-Object Status -eq 'succeeded').Count } | 
                    Select-Object -Expand Group | 
                        Select-Object "Client Name", "Save Set Name", "status", "Group" |
                            Export-Csv -NoTypeInformation E:\Report\Failed_$CurrentDate.csv

示例 2。

Client Name,Save Set Name,Group,Status
gsiecwt2020.web.local,pseudo_saveset,D_CWT_File_System_1,failed
gsiecwt2020.web.local,J:\System,D_CWT_File_System_2,succeeded
gsiecwt2020.web.local,K:\System,D_CWT_File_System_1,succeeded
gsiecwt2020.web.local,K:\System,D_CWT_File_System_3,failed

期望的输出

gsiecwt2020.web.local,pseudo_saveset,D_CWT_File_System_1,failed

它应该匹配Client NameSave Set NameStatus。 如果具有相同Save Set Name的客户端在任何其他组中成功,则应将其标记为成功,但如果具有特定Save Set Name的客户端失败,则应将其标记为Failed

【问题讨论】:

标签: powershell grouping


【解决方案1】:

您可以使用Group-ObjectWhere-Object 子句来做到这一点。

对于演示,我使用的是 Here-String;在现实生活中,你会从文件中导入 csv

$csv = Import-Csv -Path 'X:\yourInputFile.csv'

代码:

$csv = @"
Client Name,Save Set Name,Group,Status
a,All,Group1,Failed
a,SQL,Group2,succeeded
b,SQL,Group1,Failed
c,FS,Group1,Failed
d,DBA,Group1,Failed
e,RDM,Group1,Failed
a,ALL,Group2,succeeded
b,SQL,Group3,succeeded
c,SQL,Group4, Failed
"@ | ConvertFrom-Csv

$result = $csv | Group-Object 'Client Name' | ForEach-Object {
    $succeeded = $_.Group | Where-Object { $_.Status -eq 'succeeded' }
    if (!$succeeded) { $_.Group }  # never succeeded, so output these
}

# output on screen
$result | Format-Table -AutoSize

# output to CSV
$result | Export-Csv -Path 'X:\yourFilteredCsv.csv' -UseCulture -NoTypeInformation

结果:

客户端名称 存储集名称 组状态 ------------ ------------- ----- ------ c FS Group1 失败 c SQL Group4 失败 d DBA Group1 失败 e RDM 组 1 失败

看到你最新的 cmets,我想/希望我现在能更好地理解这个问题。幸运的是,代码可以很容易地调整为不仅在“客户端名称”上进行分组,还可以在“保存集名称”上进行分组,如下所示。

$result = $csv | Group-Object 'Client Name','Save Set Name' | ForEach-Object {
    # if any of the group items have a status of 'succeeded', skip that group
    $succeeded = $_.Group | Where-Object { $_.Status -eq 'succeeded' }
    if (!$succeeded) { $_.Group }  # never succeeded, so output these
}

# output on screen
$result | Format-Table -AutoSize

# output to CSV
$result | Export-Csv -Path 'X:\yourFilteredCsv.csv' -UseCulture -NoTypeInformation

使用示例 1:

客户端名称、存储集名称、组、状态 a,全部,Group1,失败 a,SQL,Group2,成功 b,SQL,Group1,失败 c,FS,Group1,失败 d,DBA,Group1,失败 e,RDM,Group1,失败 a,ALL,Group2,成功 b,SQL,Group3,成功 c,SQL,Group4,失败

产量:

客户端名称 存储集名称 组状态 ------------ ------------- ----- ------ c FS Group1 失败 d DBA Group1 失败 e RDM 组 1 失败 c SQL Group4 失败

使用示例 2:

客户端名称、存储集名称、组、状态 gsiecwt2020.web.local,pseudo_saveset,D_CWT_File_System_1,失败 gsiecwt2020.web.local,J:\System,D_CWT_File_System_2,成功 gsiecwt2020.web.local,K:\System,D_CWT_File_System_1,成功 gsiecwt2020.web.local,K:\System,D_CWT_File_System_3,失败

产量:

客户端名称 存储集名称 组状态 ------------ ------------- ----- ------ gsiecwt2020.web.local pseudo_saveset D_CWT_File_System_1 失败

【讨论】:

  • @Theo- 感谢您的努力。在您的脚本中,我面临一个问题,即它没有考虑“保存集”选项卡。如果任何保存成功,则将完成客户端标记为成功,但不应如此。我用新的例子更新了我的问题
  • @GURUSINGH 我不明白你的意思。Save Set Name 字段出现在输出中,不,它不是成功标记客户端。您的问题是找到从未成功的客户,因此在每个组中,我都在测试以查看是否有任何“成功”状态。仅当不是这种情况时,客户端才会获得输出,因为该客户端的所有状态字段都显示“失败”。附言我没有看到已编辑的问题。
  • @Theo- 问题更新了新的示例和解释。请检查
  • @Theo- 你能帮忙吗?
  • 这就是我真正想要的。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2018-04-18
  • 2013-04-08
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多