Объедините два файла CSV с помощью bash / python - PullRequest
0 голосов
/ 07 мая 2020

У меня есть два CSV-файла, которые мне нужно сопоставить / объединить:

CSV-файл1:

"ID","Name","Flavor"
"45fc754d-6a9b-4bde-b7ad-be91ae60f582","test1","m1.medium"
"83dbc739-e436-4c9f-a561-c5b40a3a6da5","test2","m1.tiny"
"ef68fcf3-f624-416d-a59b-bb8f1aa2a769","test3","m1.medium"

CSV-файл2:

"Name","RAM","Disk","VCPUs"
"m1.medium",4096,40,2
"m1.xlarge",16384,160,8
"m1.tiny",128,1,1

Идеальный результат: быть:

"ID","Name","Flavor","RAM","Disk","VCPUs"
"45fc754d-6a9b-4bde-b7ad-be91ae60f582","test1","m1.medium",4096,40,2
"83dbc739-e436-4c9f-a561-c5b40a3a6da5","test2","m1.tiny",128,1,1
"ef68fcf3-f624-416d-a59b-bb8f1aa2a769","test3","m1.medium",4096,40,2

Обратите внимание, что Flavor в CSV-файле 1 и Name в CSV-файле 2 одинаковы. Разница в названии является результатом использования разных инструментов для получения информации.

Также обратите внимание, что CSV File2 имеет flavor/name m1.xlarge. Как подробно описано выше, если m1.xlarge flavor/name не найден в CSV File1, его следует исключить из консолидированного вывода.

Я был в этом весь день со смешанными результатами. Приветствуются любые идеи.

Ответы [ 3 ]

2 голосов
/ 07 мая 2020

Вы можете использовать это awk:

awk -v hdr='"ID","Name","Flavor","RAM","Disk","VCPUs"' 'BEGIN {
   FS=OFS=","
   print hdr
}
NR == FNR {
   a[$1] = $2 FS $3 FS $4
   next
}
$3 in a {
   print $0, a[$3]
}' file2.csv file1.csv

"ID","Name","Flavor","RAM","Disk","VCPUs"
"45fc754d-6a9b-4bde-b7ad-be91ae60f582","test1","m1.medium",4096,40,2
"83dbc739-e436-4c9f-a561-c5b40a3a6da5","test2","m1.tiny",128,1,1
"ef68fcf3-f624-416d-a59b-bb8f1aa2a769","test3","m1.medium",4096,40,2
1 голос
/ 07 мая 2020

Что-то вроде этого, но вам придется поиграть с параметрами цитирования, чтобы увидеть, что вам нравится.

#!/usr/bin/env python3

import csv

by_name = {}
with open('b.csv') as b:
    for row in csv.DictReader(b):
        name = row.pop('Name')
        by_name[name] = row

with open('c.csv', 'w') as c:
    w = csv.DictWriter(c, ['ID', 'Name', 'Flavor', 'RAM', 'Disk', 'VCPUs'])
    w.writeheader()

    with open('a.csv') as a:
        for row in csv.DictReader(a):
            try:
                match = by_name[row['Flavor']]
            except KeyError:
                continue

            row.update(match)

            w.writerow(row)

Вывод:

ID,Name,Flavor,RAM,Disk,VCPUs
45fc754d-6a9b-4bde-b7ad-be91ae60f582,test1,m1.medium,4096,40,2
83dbc739-e436-4c9f-a561-c5b40a3a6da5,test2,m1.tiny,128,1,1
ef68fcf3-f624-416d-a59b-bb8f1aa2a769,test3,m1.medium,4096,40,2
0 голосов
/ 07 мая 2020

Если я правильно понял ваш вопрос, и вы хотите сопоставить строки в первом файле на основе строки в столбце Flavor со строками, которые имеют это значение в столбце Name во втором CSV, тогда это довольно легко сделать с помощью xsv (что вам, вероятно, потребуется сначала установить ):

$ xsv join "Flavor" file1.csv "Name" file2.csv
ID,Name,Flavor,Name,RAM,Disk,VCPUs
45fc754d-6a9b-4bde-b7ad-be91ae60f582,test1,m1.medium,m1.medium,4096,40,2
83dbc739-e436-4c9f-a561-c5b40a3a6da5,test2,m1.tiny,m1.tiny,128,1,1
ef68fcf3-f624-416d-a59b-bb8f1aa2a769,test3,m1.medium,m1.medium,4096,40,2

Вам также придется удалить дублируйте столбец Name, что вы можете сделать снова с xsv:

$ xsv join "Flavor" file1.csv "Name" file2.csv | xsv select ID,Name,Flavor,RAM,Disk,VCPUs
ID,Name,Flavor,RAM,Disk,VCPUs
45fc754d-6a9b-4bde-b7ad-be91ae60f582,test1,m1.medium,4096,40,2
83dbc739-e436-4c9f-a561-c5b40a3a6da5,test2,m1.tiny,128,1,1
ef68fcf3-f624-416d-a59b-bb8f1aa2a769,test3,m1.medium,4096,40,2
...