【问题标题】:Powershell Compare value to multiple arraysPowershell 将值与多个数组进行比较
【发布时间】:2019-04-06 03:23:47
【问题描述】:

我正在尝试将数据与多个来源进行比较,然后给我一份错误报告。由于异常的性质不断变化,我想构建一个 csv 格式的异常表,我可以随时更改。

我将尽我所能提供数据,并向您展示我正在努力实现的目标,并向您展示我遇到问题的地方。

例外列表包含不同类型帐户的前缀:

例外列表 _______________ FQ 问 总部 E

因此,如果我的帐户是 BND123,那么我可能有一个名为 FQBND123QBND123 的帐户,如果其中一个团队决定他们需要创建一个 JQ 帐户,我希望能够添加到此列表中或将来发生类似的事情。

这是我要解析的Inventoryreport.csv 示例:

安全目标系统用户名 HUMAN_ABC QABC HUMAN_CDE QCDE HUMAN_FGHIJ QFGHIJ HUMAN_P123456 根 HUMAN_KLMNO QKLMNO1 HUMAN_P789123 FQ789123

所以我希望将目标系统用户名与安全名称进行比较,如果主要帐户在异常列表中,则将其传递出去,如果没有,则将其作为错误抛出。

所以在上面2行数据的情况下会在下面抛出错误。

HUMAN_P123456 根 HUMAN_KLMNO QKLMNO1

出于明显的原因而根目录和KLMNO 帐户,因为尾随1


我遇到的问题是它说一切都是错误的。如果我将它输入到循环中,一切都很好。

我在 foreach 循环中也有异常,在库存循环中,但它不断循环相同的结果,仍然吐出所有内容。

希望这是一个不错的解释,我确信我让这变得比需要的更难。

$loc = $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$D = $loc + "\Exceptions\Exceptions.csv"
$E = $loc + "\Import\InventoryReport.csv"

$exceptions = Import-Csv -LiteralPath $D 
$inventory = Import-Csv -LiteralPath $E

$list2 = 'Inventory Report Exceptions'
$list3 = 'Target system user name'

$DO = $loc + "\Report\Inventory Report Errors" + "$((Get-Date).ToString('MM-dd-yyyy')).CSV"
$time = (Get-Date).ToString()

foreach ($item in $inventory) {
    $input1 = $item.Safe -replace "HUMAN_"
    $input4 = $item.Safe -replace "HUMAN_P"
    $input2 = $item.$list3
    $input3 = $item.Safe

    if ($input2 -eq ($exceptions.$list2 + $input1) -or $input2 -eq ($exceptions.$list2 + $input4)) {
        return
    }
    else {
        $newitem = New-Object -TypeName PSCustomObject -Property  @{
            Safe  = $input1
            Owner = $input2
        }| Export-CSV -LiteralPath $DO -NoTypeInformation -append
    }
}

【问题讨论】:

    标签: regex powershell csv


    【解决方案1】:

    你的问题有点长,不是很清楚...

    让我们看看我是否正确:

    • 我将例外列表缩短为锚定在开头的正则表达式
    • 使用此处的字符串模拟inventory.csv
    • 将一列 Pass 添加到该列
    • 迭代比较分割值是否相等的条目并保存在新列中。

    ## Q:\Test\2018\11\02\SO_53109141.ps1
    $Inventory = @"
    Safe,Target system user name
    HUMAN_ABC,QABC
    HUMAN_CDE,QCDE
    HUMAN_FGHIJ,QFGHIJ
    HUMAN_P123456,root
    HUMAN_KLMNO,QKLMNO1
    HUMAN_P789123,FQ789123
    "@ | ConvertFrom-Csv
    
    #$Exception = [regex]'^(FQ|Q|HQ|E)'
    $Exception = [RegEx]("^("+((Import-Csv .\exceptions.csv).'Exceptions List' -join '|')+")")
    
    $Fail = $Inventory | Select-Object *,Pass | ForEach-Object {
       if ( ($_.Safe -split '_P?')[1] -ne ($_.'Target system user name' -split $Exeption)[2]){
           [PSCustomObject]@{
              Safe = ($_.Safe -split '_')[1]
             Owner= $_.'Target system user name'
           }
        }
    }
    $Fail | Export-Csv '.\new.csv' -NoTypeInformation
    

    样本输出:

    Safe          Target system user name  Pass
    ----          -----------------------  ----
    HUMAN_ABC     QABC                     True
    HUMAN_CDE     QCDE                     True
    HUMAN_FGHIJ   QFGHIJ                   True
    HUMAN_P123456 root                    False
    HUMAN_KLMNO   QKLMNO1                 False
    HUMAN_P789123 FQ789123                 True
    

    编辑您可以从文件中读取异常:

    > import-csv .\exceptions.csv
    
    Exceptions List
    ---------------
    FQ
    Q
    HQ
    E
    

    并根据内容构建正则表达式:

    $Exception = [RegEx]("^("+((Import-Csv .\exceptions.csv).'Exceptions List' -join '|')+")")
    

    【讨论】:

    • 查看更改的答案如何从读取的 csv 中构造正则表达式。
    • 再次编辑答案以仅将失败的 [PCustomObject] 输出到 $Fail 并在最后导出
    • 我只想说我想通了!非常感谢,我对 Powershell 非常陌生,所以向像你这样的人学习有助于我成长。再次感谢您的患者和您的惊人回答。
    • 仅供参考:可能值得添加[Regex]::Escape;即将((Import-Csv .\exceptions.csv).'Exceptions List'修改为(((Import-Csv .\exceptions.csv).'Exceptions List' | %{[Regex]::Escape($_)});这样,如果值中包含任何特殊字符,它们就不会干扰预期的逻辑。
    • 规则列表越来越长,IMO 超出了单个问题的范围。我不清楚如何处理 HUMAN_Pxx 和尾随 _CA,这应该是这个问题的一部分——或者是一个新问题,但一次只有一个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2018-05-29
    • 2013-05-01
    相关资源
    最近更新 更多