我有2个CSV
left.csv
Ref_ID,First_Name,Last_Name,DOB
321364060,User1,Micah,11/01/1969
946497594,User2,Acker,05/28/1960
887327716,User3,Aco,06/26/1950
588496260,User4,John,05/23/1960
565465465,User5,Jack,07/08/2020
right.csv
First_Name,Last_Name,DOB,City,Document_Type,Filename
User1,Micah,11/01/1969,Parker,Transcript,T4IJZSYO.pdf
User2,Acker,05/28/1960,,Transcript,R4IKTRYN.pdf
User3,Aco,06/26/1950,,Transcript,R4IKTHMK.pdf
User4,John,05/23/1960,,Letter,R4IKTHSL.pdf
最终结果:
Combined.csv
Ref_ID,First_Name,Last_Name,DOB,Document_Type,Filename
321364060,User1,Micah,11/01/1969,Parker,Transcript,T4IJZSYO.pdf
946497594,User2,Acker,05/28/1960,Transcript,R4IKTRYN.pdf
887327716,User3,Aco,06/26/1950,Transcript,R4IKTHMK.pdf
588496260,User4,John,05/23/1960,Letter,R4IKTHSL.pdf
我需要在First_Name,Last_Name,DOB上进行匹配,然后从左侧返回Ref_ID,first_name,last_name,DOB。csv和从右侧返回Document_Type,Filename。csv
使用Compare-Object:仅返回其中一个csv的列,而不返回两个中的列。
使用join-object:这是我的巨大希望,但是那只能让我在一个列上进行匹配,我需要匹配多个列(不能弄清楚如何做多个)
我不确定从这里去哪里,欢迎提出建议。
答案 0 :(得分:2)
$left = Import-Csv C:\left.csv
$right = Import-Csv C:\right.csv
Compare-Object -ReferenceObject $left -DifferenceObject $right -Property First_Name,Last_Name,DOB -IncludeEqual -ExcludeDifferent |
ForEach-Object {
$iItem = $_
$ileft = $left.Where({$_.First_Name -eq $iItem.First_Name -and $_.Last_Name -eq $iItem.Last_Name -and$_.DOB -eq $iItem.DOB})
$iright = $right.Where({$_.First_Name -eq $iItem.First_Name -and $_.Last_Name -eq $iItem.Last_Name -and$_.DOB -eq $iItem.DOB})
[pscustomobject]@{
Ref_ID=$ileft.Ref_ID
first_name=$ileft.first_name
last_name=$ileft.last_name
DOB=$ileft.DOB
Document_Type=$iright.Document_Type
Filename=$iright.Filename
}
} | Export-Csv C:\Combined.csv -NoTypeInformation
答案 1 :(得分:1)
您可以从每个csv创建自己的密钥,然后使用此密钥从每个csv将其添加到新的哈希表中。
在调试器(ISE或VSCode)中逐步解决此问题,并根据需要进行调整... 根据数据的完整性,根据需要添加适当的错误检查。 下面的一些语句仅用于调试,因此您可以检查其运行时发生的情况。
# Ref_ID,First_Name,Last_Name,DOB
$csv1 = @'
321364060,User1,Micah,11/01/1969
946497594,User2,Acker,05/28/1960
887327716,User3,Aco,06/26/1950
588496260,User4,John,05/23/1960
565465465,User5,Jack,07/08/2020
'@
# First_Name,Last_Name,DOB,City,Document_Type,Filename
$csv2 = @'
User1,Micah,11/01/1969,Parker,Transcript,T4IJZSYO.pdf
User2,Acker,05/28/1960,,Transcript,R4IKTRYN.pdf
User3,Aco,06/26/1950,,Transcript,R4IKTHMK.pdf
User4,John,05/23/1960,,Letter,R4IKTHSL.pdf
'@
# hashtable
$data = @{}
$c1 = $csv1 -split "`r`n"
$c1.count
foreach ($item in $c1)
{
$fields = $item -split ','
$key = $fields[1]+$fields[2]+$fields[3]
$key
# add new hashtable for given key
$data.Add($key, [ordered]@{})
# add data from c1 to the hashtable
$data[$key].ID = $fields[0]
$data[$key].First = $fields[1]
$data[$key].Last = $fields[2]
$data[$key].DOB = $fields[3]
}
$c2 = $csv2 -split "`r`n"
$c2.count
foreach ($item in $c2)
{
$fields = $item -split ','
$key = $fields[0]+$fields[1]+$fields[2]
$key
# add data from c2 to the hashtable
$data[$key].Type = $fields[4]
$data[$key].FileName = $fields[5]
}
$data.Count
foreach ($key in $data.Keys)
{
'====================='
$data[$key]
}
答案 2 :(得分:1)
尝试Join-Object。
它具有更多功能以及基于多个列的联接:
$Left = ConvertFrom-Csv @"
Ref_ID,First_Name,Last_Name,DOB
321364060,User1,Micah,11/01/1969
946497594,User2,Acker,05/28/1960
887327716,User3,Aco,06/26/1950
588496260,User4,John,05/23/1960
565465465,User5,Jack,07/08/2020
"@
$Right = ConvertFrom-Csv @"
First_Name,Last_Name,DOB,City,Document_Type,Filename
User1,Micah,11/01/1969,Parker,Transcript,T4IJZSYO.pdf
User2,Acker,05/28/1960,,Transcript,R4IKTRYN.pdf
User3,Aco,06/26/1950,,Transcript,R4IKTHMK.pdf
User4,John,05/23/1960,,Letter,R4IKTHSL.pdf
"@
$Left | Join $Right `
-On First_Name, Last_Name, DOB `
-Property Ref_ID, Filename, First_Name, DOB, Last_Name `
| Format-Table
Last_Name Ref_ID DOB Filename First_Name
--------- ------ --- -------- ----------
Micah 321364060 1969-11-01 12:00:00 AM T4IJZSYO.pdf User1
Acker 946497594 1960-05-28 12:00:00 AM R4IKTRYN.pdf User2
Aco 887327716 1950-06-26 12:00:00 AM R4IKTHMK.pdf User3
John 588496260 1960-05-23 12:00:00 AM R4IKTHSL.pdf User4
答案 3 :(得分:1)
已经有一些好的答案,这是另一个。
将大量对象导入单个(分散)数组:
os.rename(filename + '.fixed', filename)
使用$left = @"
Ref_ID,First_Name,Last_Name,DOB
321364060,User1,Micah,11/01/1969
946497594,User2,Acker,05/28/1960
887327716,User3,Aco,06/26/1950
588496260,User4,John,05/23/1960
565465465,User5,Jack,07/08/2020
"@
$right = @"
First_Name,Last_Name,DOB,City,Document_Type,Filename
User1,Micah,11/01/1969,Parker,Transcript,T4IJZSYO.pdf
User2,Acker,05/28/1960,,Transcript,R4IKTRYN.pdf
User3,Aco,06/26/1950,,Transcript,R4IKTHMK.pdf
User4,John,05/23/1960,,Letter,R4IKTHSL.pdf
"@
$disarray = @(
$left | ConvertFrom-Csv
$right | ConvertFrom-Csv
)
将它们分为具有相同键值的组:
Group-Object
然后合并对象,将所有缺少的属性添加到输出$keyProps = @('First_Name', 'Last_name', 'DOB')
$disarray |
Group-Object -Property $keyProps |
Where-Object Count -gt 1 |
$mergedObject
这与您已经拥有的答案没有很大不同,但是消除“左”与“右”的区别可能会有所帮助;上面的代码应处理抛出到 ForEach-Object {
$mergedObject = $_.group[0]
foreach ($obj in $_.group[1..($_.group.count-1)]) {
$newProps = ($obj | Get-Member -MemberType NoteProperty).name |
Where-Object {
$_ -notin ($mergedobject | Get-Member -MemberType NoteProperty).name
}
foreach ($propName in $newProps) {
$mergedObject | Add-Member -MemberType NoteProperty -Name $propName -Value $obj.$propName -Force
}
}
Write-Output $mergedObject
}
中的三个或更多源,合并包含相同$disarray
的所有对象。
请注意,有一些极端情况需要考虑。例如,如果一个对象的用户名称为“ City = Chigago”,而另一个对象的名称为“ City = New York”,该怎么办?
答案 4 :(得分:0)
添加我发现的答案
$left = Import-Csv .\left.csv
$right = Import-Csv .\right.csv
$right | foreach {
$r = $_;
$left | where{ $_.First_Name -eq $r.First_Name -and $_.Last_Name -eq $r.Last_Name -and $_.DOB -eq $r.DOB } |
select Ref_Id,
First_Name,
Last_Name,
DOB,
@{Name="City";Expression={$r.City}},
@{Name="Document_Type";Expression={$r.Document_Type}},
@{Name="FileName";Expression={$r.FileName}}
} | format-table