比较 2 个 csv 文件并根据 1 列进行匹配,然后导出包含两个字段的新文件
Compare 2 csv files and match based on 1 column then export new file that contains fields from both
我有 2 个 csv 文件。每个都有不同的 header 和不同的列数,并且有不同的条目数。
以下是前几行的一些示例
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
我一直在寻找并发现这个 Whosebug 从大约一年前开始,它似乎在正确的轨道上,但我似乎无法根据我的需要修改代码。这是我尝试过的。
$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
我在新文件中获得了正确的 header,但我从未获得名称 ID 值。
知道我哪里出错了吗?我可能完全走错了路,有更简单的方法,但我需要能够在没有用户交互的情况下每晚执行此操作。任何帮助表示赞赏!
您要查找的操作称为关系连接。有时称为内部连接,有时称为连接。我对连接的了解来自 SQL,而不是 Powershell。
这里是 "Join-Object" 的描述。这似乎是你要找的。
http://blogs.msdn.com/b/powershell/archive/2012/07/13/join-object.aspx
让我们试着简化一下。将 'Name 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'
}
$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 -属性 "Value" 来操作它们像这样
$objlength = $nameobject |select "First_Name"
$objlength.length
但我更喜欢直接从对象调用它,因为输出看起来像这样更清晰
$nameobject."First_Name".length
我有 2 个 csv 文件。每个都有不同的 header 和不同的列数,并且有不同的条目数。
以下是前几行的一些示例
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
我一直在寻找并发现这个 Whosebug 从大约一年前开始,它似乎在正确的轨道上,但我似乎无法根据我的需要修改代码。这是我尝试过的。
$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
我在新文件中获得了正确的 header,但我从未获得名称 ID 值。
知道我哪里出错了吗?我可能完全走错了路,有更简单的方法,但我需要能够在没有用户交互的情况下每晚执行此操作。任何帮助表示赞赏!
您要查找的操作称为关系连接。有时称为内部连接,有时称为连接。我对连接的了解来自 SQL,而不是 Powershell。
这里是 "Join-Object" 的描述。这似乎是你要找的。
http://blogs.msdn.com/b/powershell/archive/2012/07/13/join-object.aspx
让我们试着简化一下。将 'Name 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'
}
$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 -属性 "Value" 来操作它们像这样
$objlength = $nameobject |select "First_Name"
$objlength.length
但我更喜欢直接从对象调用它,因为输出看起来像这样更清晰
$nameobject."First_Name".length