如何在此使用Group-Object?

时间:2017-08-03 18:54:04

标签: powershell csv

我正在尝试将$table4中与$accounts中的帐户不匹配的所有帐户转换为$f。但我还需要检查入住人数是否匹配。

CSV $table4

Account_no |occupant_code
-----------|------------
12345      |    1
67890      |    2
45678      |    3

DataTable $accounts = Import-Csv $f | select account_no, occupant_code | where { $table4.account_no -notcontains $_.account_no }

Account_no |occupant_code
-----------|------------
12345      |   1
67890      |   1
45678      |   3

当前代码:

occupant_code

这需要做的是检查$f是否匹配,即:

  • 12345 :来自$table4$table4的帐户和占用者匹配;所以它被忽略了
  • 67890 :帐户与$accounts匹配,但occupancy_code不匹配,因此会将其添加到67890

目前的结果:
期望的结果:Group-Object

我相信我需要使用Import-Csv $f | select account_no, occupant_code | Group-Object account_no | Where-Object { $_.Group.occupant_code -notcontains $table4.occupant_code } ,但我不知道如何正确使用它。

我试过了:

{{1}}

4 个答案:

答案 0 :(得分:1)

Account_no,occupant_code 12345,1 67890,2 45678,3

csv1.csv:

Account_no,occupant_code
12345,1
67890,1
45678,3

csv2.csv:

Compare-Object (Import-Csv .\csv1.csv) (Import-Csv .\csv2.csv) -Property occupant_code -PassThru

PowerShell命令:

Account_no occupant_code SideIndicator
---------- ------------- -------------
67890      1             =>
67890      2             <=

输出:

viewww = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height - navBar.frame.height))

答案 1 :(得分:1)

Bill's suggestion的替代方法是使用您的参考数据($table4)填充hashtable,并从occupant_code查找每个帐户的$f值},假设您的帐号是唯一的:

$ref = @{}
$table4 | ForEach-Object {
    $ref[$_.Account_no] = $_.occupant_code
}

$accounts = Import-Csv $f |
            Where-Object { $_.occupant_code -ne $ref[$_.Account_no] } |
            Select-Object -Expand Account_no

答案 2 :(得分:0)

$f | InnerJoin $table4 {$Left.Account_no -eq $Right.Account_no -and $Left.occupant_code -ne $Right.occupant_code} @{Account_no = {$Left.$_}} | Format-Table

结果:

occupant_code Account_no
------------- ----------
{2, 1}        67890

有关详细信息,请参阅:In Powershell, what's the best way to join two tables into one?

答案 3 :(得分:0)

除了所有其他答案之外,您可以在数组上使用IndexOf()方法

$services = get-service
$services.name.IndexOf("xbgm")
240

我现在在平板电脑上并没有方便的方法来测试它,但这些方面的内容可能适合你:

$table4.account_no.IndexOf($_.account_no)

应该为$ table 4获取你的account_no所在的索引,所以你可以把它全部塞进一个丑陋的管道中:

$accounts = Import-Csv $f | select account_no, occupant_code |
            where { ($table4.account_no -notcontains $_.account_no) -or ($table4[$table4.account_no.IndexOf($_.account_no)].occupant_code -ne $_.occupant_code) }

内连接或普通循环可能只是更干净,特别是如果你想添加其他东西。由于有人发布了一个内连接,你可以尝试一个循环:

$accounts = new-object System.Collections.ArrayList
$testSet = $table4.account_no
foreach($myThing in Import-Csv $f)
{
    if($myThing.account_no -in $testSet )
    {
        $i = $testSet.IndexOf($myThing.account_no)
        if($table4[$i].occupant_code -eq $myThing.occupant_code) {continue}
    }

    $accounts.add($myThing)
}

编辑OP,他提到$ table4是一个data.table 可能有更好的方法来做到这一点,因为我之前没有使用过data.table,但这似乎工作正常:

$table = New-Object system.Data.DataTable
$col1 = New-Object system.Data.DataColumn Account_no,([string])
$col2 = New-Object system.Data.DataColumn occupant_code,([int])
$table.columns.add($col1)
$table.columns.add($col2)

$row = $table.NewRow()
$row.Account_no = "12345"
$row.occupant_code = 1
$table.Rows.Add($row)

$row = $table.NewRow()
$row.Account_no = "67890"
$row.occupant_code = 1
$table.Rows.Add($row)

$row = $table.NewRow()
$row.Account_no = "45678"
$row.occupant_code = 3
$table.Rows.Add($row)

$testList = @()
$testlist += [pscustomobject]@{Account_no = "12345"; occupant_code = 1}
$testlist += [pscustomobject]@{Account_no = "67890"; occupant_code = 2}
$testlist += [pscustomobject]@{Account_no = "45678"; occupant_code = 3}

$accounts = new-object System.Collections.ArrayList
$testSet = $table.account_no
foreach($myThing in $testList)
{
    if($myThing.account_no -in $testSet )
    {
        $i = $testSet.IndexOf($myThing.account_no)
        if($table.Rows[$i].occupant_code -eq $myThing.occupant_code) {continue}
    }

    $accounts.add($myThing) | out-null
}

$accounts