Объединить два CSV-файла на основе совпадающих данных столбцов

Объединить два CSV-файла на основе совпадающих данных столбцов

Я хотел бы объединить данные из двух CSV-файлов на основе информации о совпадающих столбцах. Данные для сопоставления находятся в столбце 5 файла File1.csv и столбце 1 файла File2, и я хочу добавить информацию из столбца 2 файла File2 при сопоставлении, а если совпадений нет, оставить пустые двойные кавычки.

Файл1.csv

"Z","P","W","K","1","1.18.24.59"
"S","K","D","X","9","1.14.19.238"
"R","M","P","Y","8","1.15.11.21"
"B","D","0","U","5","1.9.20.159"
"R","E","W","Q","6","135.0.0.1"
"K","D","K","R","9","1.9.74.13"

Файл2.csv

"65.9.7.19","374 22 53"
"1.9.74.13","123 256 51"
"1.18.24.59","23 25 41"
"1.15.11.21","98 77 8291"
"1.14.19.238","8827 145 8291"
"1.9.20.159","283 1 5734"

Желаемый результат

"Z","P","W","K","1","1.18.24.59","23 25 41"
"S","K","D","X","9","1.14.19.238","8827 145 8291"
"R","M","P","Y","8","1.15.11.21","98 77 8291"
"B","D","0","U","5","1.9.20.159","283 1 5734"
"R","E","W","Q","6","135.0.0.1",""
"K","D","K","R","9","1.9.74.13","123 256 51"

решение1

Вот одно из решений с использованием awk. Протестировано на GNU awk 4.1.3.

$ awk -F, 'NR==FNR{a[$1]=$2}NR!=FNR{print $0","(a[$6]?a[$6]:"\"\"")}' file2.csv file1.csv
"Z","P","W","K","1","1.18.24.59","23 25 41"
"S","K","D","X","9","1.14.19.238","8827 145 8291"
"R","M","P","Y","8","1.15.11.21","98 77 8291"
"B","D","0","U","5","1.9.20.159","283 1 5734"
"R","E","W","Q","6","135.0.0.1",""
"K","D","K","R","9","1.9.74.13","123 256 51"
$
  • Сопоставляет NR==FNR{a[$1]=$2строки в файле file2 и добавляет их в массив, ключом к которому служит поле №1.
  • Затем он NR!=FNRсопоставляет строки в файле file1.
  • print $0","печатает всю строку из файла file1, за которой следует запятая.
  • (a[$6]?a[$6]:"\"\"")выводит соответствующее содержимое массива, созданного ранее, но только ""если запись не найдена.

решение2

Это оказалось сложнее, чем я ожидал, но с инструментами из csvkitверсии 1.0.2 на основе Python:

$ csvjoin -HI -c 6,1 --left File1.csv File2.csv 2>/dev/null | csvformat -K1 -U1
"Z","P","W","K","1","1.18.24.59","23 25 41"
"S","K","D","X","9","1.14.19.238","8827 145 8291"
"R","M","P","Y","8","1.15.11.21","98 77 8291"
"B","D","0","U","5","1.9.20.159","283 1 5734"
"R","E","W","Q","6","135.0.0.1",""
"K","D","K","R","9","1.9.74.13","123 256 51"

( -IПо-видимому, это необходимо для того, чтобы не допустить csvjoinпредположения, что поля, разделенные точками, представляют собой дату и время, по крайней мере в моей локали.)

решение3

for i in `cat file2.csv | awk -F "," '{print $1}'| sed 's/"//g'`; do j=`sed -n '/'$i'/p' file2.csv| awk -F "," '{print $2}'| sed 's/"//g'`;awk -v i="$i" -v j="$j" -F "," '$NF==i{$7=j;print $0}' file1.csv; done| sed 's/ /","/g'| sed 's/^/"/g'| sed 's/$/"/g'

выход

"Z","P","W","K","1","1.18.24.59","23 25 41"
"S","K","D","X","9","1.14.19.238","8827 145 8291"
"R","M","P","Y","8","1.15.11.21","98 77 8291"
"B","D","0","U","5","1.9.20.159","283 1 5734"
"R","E","W","Q","6","135.0.0.1",""
"K","D","K","R","9","1.9.74.13","123 256 51"

Связанный контент