比较两个csv文件中的列

时间:2013-08-21 17:09:40

标签: powershell

有了所有的例子,你会认为我可以找到我的解决方案。 : - )

无论如何,我有两个csv文件;一个有两列,一个有4.我需要使用powershell比较每一列的一列。我以为我已经想通了,但是当我对结果进行比较时,当我知道它应该是真的时,它会回复为假。这是我到目前为止所做的:

 $newemp = Import-Csv -Path "C:\Temp\newemp.csv" -Header login_id, lastname, firstname, other | Select-Object "login_id"
 $ps = Import-Csv -Path "C:\Temp\Emplid_LoginID.csv" | Select-Object "login id"
 If ($newemp -eq $ps)
    {
      write-host "IDs match" -forgroundcolor green
    }
 Else 
    {
      write-host "Not all IDs match" -backgroundcolor yellow -foregroundcolor black
    }

我必须为第一个文件指定标题,因为它没有任何标题。奇怪的是,我可以调用每个变量来查看它所拥有的内容,并且最终会得到相同的信息,但由于某些原因仍然会出现错误。即使只有一行(不计算标题行),也会发生这种情况。

我开始将它们解析为数组但不太确定这是正确的。重要的是我将第一个文件的row1与第二个文件的row1进行比较。我不能只做一个简单的匹配或 - 包含。

编辑:一件令人讨厌的事情是,变量似乎也包含标题行。当我呼叫每个人时,会显示标题。但是,如果我调用两个变量,我只看到一个标题但只有两行。

我刚刚添加了以下检查但获得了相同的结果(对于所有内容都是假的):

    $results = Compare-Object -ReferenceObject $newemp -DifferenceObject $ps -PassThru | ForEach-Object { $_.InputObject }

3 个答案:

答案 0 :(得分:3)

使用来自here的latkin答案我认为这会为您提供您正在寻找的结果集。根据拉特金的评论,为了您的目的,财产比较是多余的,但我把它留在了,因为它很好。此外,即使对于带有标题的csv,也会指定标题,以防止标题行包含在比较中。

$newemp = Import-Csv -Path "C:\Temp\_sotemp\Book1.csv" -Header loginid | 
    Select-Object "loginid"

$ps = Import-Csv -Path "C:\Temp\_sotemp\Book2.csv" -Header loginid | 
    Select-Object "loginid"

#get list of (imported) CSV properties
$props1 = $newemp | gm -MemberType NoteProperty | select -expand Name | sort
$props2 = $ps | gm -MemberType NoteProperty | select -expand Name | sort

#first check that properties match 
#omit this step if you know for sure they will be
if(Compare-Object $props1 $props2){
    throw "Properties are not the same! [$props1] [$props2]"
}

#pass properties list to Compare-Object
else{
    Compare-Object $newemp $ps -Property $props1
}

答案 1 :(得分:2)

在第二行,我看到有一个空格“登录ID”,第一行没有它。这可能是一个问题。尝试在.csv文件本身中使用相同的名称。它适用于不提供标题或选择语句。以下是我根据您的输入进行的实验。

<强> emp.csv

loginid      firstname  lastname
------------------------------
abc123   John       patel  
zxy321   Kohn       smith  
sdf120   Maun       scott  
tiy123   Dham       rye  
k2340    Naam       mason  
lk10j5   Shaan      kelso  
303sk    Doug       smith  

<强> empids.csv

loginid
-------  
abc123  
zxy321  
sdf120  
tiy123  
  

PS C:\&gt; $ newemp = Import-csv C:\ scripts \ emp.csv
  PS C:\&gt; $ ps = Import-CSV C:\ scripts \ empids.csv
  PS C:\&gt; $ results = Compare-Object -ReferenceObject $ newemp -DifferenceObject $ ps | foreach {$ _.InputObject}

显示不在$ ps

中的差异对象
loginid  firstname  lastname   SideIndicator  
-------  ---------  --------   -------------  
k2340    Naam       mason      <=  
lk10j5   Shaan      kelso      <=  
303sk    Doug       smith      <=  

答案 2 :(得分:2)

我不确定这是否是您要找的,但我已经使用PowerShell为自己做了一些CSV格式化。

            $test = Import-Csv .\Desktop\Vmtools-compare.csv
                foreach ($i in $test) {
                    foreach ($n in $i.name) {    
                        foreach ($m in $test) {
                            $check = "yes"         
                            if ($n -eq $m.prod) {
                                $check = "no"
                                break
                            }
                        }
                    if ($check -ne "no") {$n}
                    }
                }

这就是我的excel csv文件的样子:

prod    name
1       3
2       5
3       8
4       2
5       0

和脚本输出:

8
0

所以基本上脚本会在Name列下获取每个数字,然后根据prod列进行检查。如果数字在那里,那么它将不会显示,否则它将显示该数字。

我也以相反的方式做到了:

        $test = Import-Csv c:\test.csv                
            foreach ($i in $test) {
                foreach ($n in $i.name) {                    
                    foreach ($m in $test) {
                        $check = "yes"                         
                        if ($n -eq $m.prod) {echo $n}
                    }
                }
            }

这就是我的excel csv的样子:

prod    name
1       3
2       5
3       8
4       2
5       0

和脚本输出:

3
5
2

因此脚本仅显示匹配的条目。

您可以使用代码来查看不同的列。