奇怪的PowerShell问题,?范围?

时间:2013-11-12 16:03:17

标签: powershell-v2.0

我正在尝试编写一个过滤掉DataTable中重复条目的函数。我的代码工作正常,但只有行:3-4不在评论中。我尝试将$ tbl1变量的默认范围更改为全局,但它没有帮助。

我在做什么?代码如下。

Function RemoveDuplicates
{
    #$tbl1 | export-csv ".\tmp.csv"   #Code works perfectly when you uncomment these two lines.
    #$tbl1 = import-csv ".\tmp.csv"   #

    $t_tbl = $tbl1 | Sort-Object -Property Prop3 -Unique
    $duplicates = Compare-Object -ReferenceObject $tbl1 -DifferenceObject $t_tbl -Property Prop3
    #$duplicates

    write-host "tbl1 count: $($tbl1.Rows.Count)"
    write-host "t_tbl count: $($t_tbl.Count)"
    write-host "duplicates count: $(@($duplicates).Count)"

    write-host "Found $($tbl1.Rows.Count) entries. $($t_tbl.Count) entries have unique Prop3. Duplicates: $(@($duplicates).count)"
}
    $tbl1 = New-Object System.Data.DataTable
    $col1 = New-Object System.Data.DataColumn Prop1,([string])
    $col2 = New-Object System.Data.DataColumn Prop2,([string])
    $col3 = New-Object System.Data.DataColumn Prop3,([string])
    $tbl1.Columns.Add($col1)
    $tbl1.Columns.Add($col2)
    $tbl1.Columns.Add($col3)

    $row = $tbl1.NewRow()
            $row.Prop1 = "Jane"
            $row.Prop2 = "Doe"
            $row.Prop3 = "jane.doe@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Jack"
            $row.Prop2 = "Awesome"
            $row.Prop3 = "jane.doe@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Julia"
            $row.Prop2 = "Whatever"
            $row.Prop3 = "test@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Mr"
            $row.Prop2 = "ScriptGuy!"
            $row.Prop3 = "scriptguy@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Mrs"
            $row.Prop2 = "ScriptLady!"
            $row.Prop3 = "scriptlady@domain.local"
        $tbl1.Rows.Add($row)

    RemoveDuplicates

谢谢

1 个答案:

答案 0 :(得分:0)

不幸的是,它与范围无关。它与数据类型有关。

这可能令人沮丧:

Compare-Object采用两个数组并通过它们枚举两者来查找不同的项。作为测试,让我们看看PowerShell如何枚举$tbl1foreach关键字与对象和数组的参数解析行为非常相似。

foreach($row in $tbl1) { $_ }

输出为空白。这是因为它被视为单个对象,而不是集合。 PowerShell cmdlet参数解析不会枚举默认的集合变量。但是,如果我们通过管道推送表,

$tbl1 | % { $_ }

我们获取每一行的数据:

Prop1                                                       Prop2                                                      Prop3                                                     
-----                                                       -----                                                      -----                                                     
Jane                                                        Doe                                                        jane.doe@domain.local                                     
Jack                                                        Awesome                                                    jane.doe@domain.local                                     
Julia                                                       Whatever                                                   test@domain.local                                         
Mr                                                          ScriptGuy!                                                 scriptguy@domain.local                                    
Mrs                                                         ScriptLady!                                                scriptlady@domain.local  

然后,行$t_tbl = $tbl1 | Sort-Object -Property Prop3 -Unique将创建从Sort对象命令输出的对象数组,事实上,如果我们执行以下操作:$t_tbl.GetType().FullName; $ tbl | Select-Object -First 1 | %{$ .GetType()。FullName},我们看到它是System.Object[](数组),其中每个项目都是System.Data.DataRow个实例。 $tbl1但是System.Data.DataTable实例,而不是数组。

因此,当Compare-Object完成它的工作时,它正在将数据行数组与单个数据表进行比较。当这些行被注释掉时,请注意$duplicates的内容。

# Output of Compare-Object -ReferenceObject $tbl1 -DifferenceObject $t_tbl -Property Prop3
Prop3                   SideIndicator
-----                   -------------
jane.doe@domain.local   =>           
scriptguy@domain.local  =>           
scriptlady@domain.local =>           
test@domain.local       =>           
                        <=           

参数ReferenceObjectDifferenceObject是期​​待数组。当我们传递DifferenceObject数组时,我们将ReferenceObject传递给一个值,cmdlet将其视为大小为1的数组。

DataTable没有Prop3可供比较。

当你取消注释这些行时,你将CSV文件的内容拉回来,你没有得到一个DataTable对象。您将获得一组System.Management.Automation.PSCustomObject个实例,其中包含基于CSV文件中的列的成员属性。在这种情况下,Compare-Object现在有两个要比较的数组,两个都有具有Prop3属性的对象。

如果您只需要获取数据表中一列的唯一值,请尝试以下操作:

$tbl1 | Select-Object -ExpandProperty Prop3 | Get-Unique