Сравните два CSV, сопоставьте столбцы в 2 или более столбцах, экспортируйте определенные столбцы из обоих CSV с помощью PowerShell - PullRequest
0 голосов
/ 08 сентября 2018

у меня есть 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 из left.csv и Document_Type, Filename из right.csv

Использовать объект сравнения: он возвращает столбцы только одного из csvs, а не столбцы обоих.

Использование join-object : Это была моя большая надежда, но это позволяет мне сопоставлять только один столбец, мне нужно сопоставить несколько столбцов (не могу понять, как сделать несколько)

Я не уверен, куда идти, открыты для предложений.

Ответы [ 5 ]

0 голосов
/ 12 сентября 2018

добавив ответ, который я нашел:

$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
0 голосов
/ 09 сентября 2018

Уже есть несколько хороших ответов, а вот еще один.

Импорт множества объектов в один массив (dis):

$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, объединяя все объекты, содержащие идентичные $keyProps.

Обратите внимание, что есть угловые случаи для рассмотрения. Например, что произойдет, если у одного объекта будет «City = Chigago» для пользователя, а у другого - «City = New York»?

0 голосов
/ 08 сентября 2018
$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
0 голосов
/ 08 сентября 2018

Попробуйте это 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
0 голосов
/ 08 сентября 2018

Вы можете создать свой собственный ключ из каждого 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]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...