【问题标题】:Compare 2 csv files and match based on 1 column then export new file that contains fields from both比较 2 个 csv 文件并基于 1 列进行匹配,然后导出包含两者字段的新文件
【发布时间】:2015-05-07 06:41:42
【问题描述】:

我有 2 个 csv 文件。每个都有不同的标题和不同的列数,并且有不同的条目数。

以下是前几行的一些示例

CSV 1

    ID,Last_Name,First_Name,Middle_Name,Email_Addr,Title,Gender
    ###1,smith,bill,p,smith@soso.com,boss,m
    ###2,smith2,billy,p,smith2@soso.com,someguy,m

CSV 2

    ID,Name Id,Last Name,First Name,Middle Name,Gender
    ###2,ID1010,smith2,billy,p,M

我正在尝试导入它们并比较 ID 列。当找到匹配项时,我想要一个新的 csv 文件,其中包含来自 CSV 1 的所有信息和来自 csv 2 的匹配名称 ID。

新的 CSV 示例:

    ID,Last_Name,First_Name,Middle_Name,Email_Addr,Title,Gender,Name Id
    ###1,smith,bill,p,smith@soso.com,boss,m,
    ###2,smith2,billy,p,smith2@soso.com,someguy,m,ID1010

大约一年前,我一直在寻找并发现这个Stackoverflow,它似乎在正确的轨道上,但我似乎无法根据我的需要修改代码。这是我尝试过的。

    $csv1 = Import-Csv -Path C:\STAFF\test1sky.csv
    $csv2 = Import-Csv -Path C:\STAFF\test1power.csv

    ForEach($Record in $csv2){
    $MatchedValue = (Compare-Object $csv1 $Record -Property "ID" -IncludeEqual -ExcludeDifferent -PassThru).value
    $Record = Add-Member -InputObject $Record -Type NoteProperty -Name "Name Id" -Value $MatchedValue
    }
    $csv2|Export-Csv 'C:\STAFF\combined.csv' -NoTypeInformation

我在新文件中得到了正确的标题,但我从来没有得到名称 ID 值。

知道我哪里出错了吗?我可能完全走错了路,有一种更简单的方法,但我需要能够在没有用户交互的情况下每晚执行此操作。任何帮助表示赞赏!

【问题讨论】:

    标签: powershell csv merge


    【解决方案1】:

    让我们试着简化一下。将“名称 ID”字段添加到 CSV1 中的所有记录。然后遍历它,获取匹配项,并更新字段。比如:

    $CSV1 = C:\Path\To\File1.csv
    $CSV2 = C:\Path\To\File2.csv
    $CSV1|ForEach{$_|Add-Member 'Name ID' $Null}
    ForEach($Record in $CSV1){
        $Record.'Name ID' = $CSV2|Where{$_.ID -eq $Record.ID}|Select -Expand 'Name ID'
    }
    

    【讨论】:

    • 效果很好。谢谢您的帮助。运行大约需要 5 分钟,以便告诉您我的 csv 文件有多长。
    【解决方案2】:
    $CSV1 = import-csv C:\Path\To\File1.csv
    $CSV2 = import-csv C:\Path\To\File2.csv
    
    #adds a row named "Name ID" to the PS Object( the CSV Import)
    $CSV1|ForEach{$_|Add-Member 'Name ID' $Null}
    
    ForEach($Record in $CSV1){
    
    #gets the value from CSV1 for comparing to CSV2 
    $NameValue=Record."Last_Name"
    
    #gets the Power Shell Object from the CSV2 Import that matches the Name ID from $csv1
    $Nameobject= $CSV2|Where-object "Last Name" -contains $Namevalue
    
    #Sets the Field "Name ID" in the PS Object $CSV1 Record to the Name ID from $csv2 
    $record."Name ID" = $Nameobject."Name ID"
    }
    

    您可以通过操作 CSV2 PS 对象向 CSV1 文件添加其他引用来轻松获取其他字段。

    $record."Middle Name" = $nameobject."Middle_Name" 
    

    由于您在 for 循环表单 $csv2 中拥有整个对象,因此您可以调用其任何字段或使用变量和“ |select -Property "Value" 像这样操作它们

    $objlength = $nameobject |select "First_Name"
    $objlength.length
    

    但我更喜欢直接从对象调用它,因为输出看起来像这样更干净

    $nameobject."First_Name".length  
    

    【讨论】:

      【解决方案3】:

      您要查找的操作称为关系连接。有时它被称为内部连接,有时只是一个连接。我的 join 知识来自 SQL,而不是 Powershell。

      这里是“Join-Object”的描述。这似乎是您正在寻找的。​​p>

      http://blogs.msdn.com/b/powershell/archive/2012/07/13/join-object.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多