объединить строки на основе строки в 2 столбцах 2 файлов

объединить строки на основе строки в 2 столбцах 2 файлов

У меня есть file1 с 3 столбцами и file2 с 4 столбцами в системе Linux. Как мне объединить два файла на основе строки в столбце 3 file1 со строкой в ​​столбце 2 file2? File2 — это большая база данных со множеством записей. Столбцы 3 и 2 file1 и file2 соответственно разделяют только несколько строк. Я хотел бы вывести file1 с объединенными строками file2 в случае совпадения строк и вывести прочерк для записей без совпадений.

файл1:

300 100 a101
450 410 a400
670 710 a20
700 610 a340

файл2:

b30  a340 tttttttt 456
b500 a200 llllllll 567
b60  a101 uuuuuuuu 344
b40  a50  kkkkkkkk 223

выход:

300 100 a101 b60 a101 uuuuuuuu 344
450 410 a400 -
670 710 a20  -
700 610 a340 b30 a340 tttttttt 456

решение1

Используя GNU awkи GNU join, которые являются стандартными для Linux (могут работать или не работать с версиями, отличными от GNU):

$ join -a1 -1 3 -2 2 <(sort -k3,3 file1) <(sort -k2,2 file2) | 
    awk '$4 == "" { $4 = "-" }; {t=$1; $1=$2; $2=$3; $3=t; print}' |
    sort
300 100 a101 b60 uuuuuuuu 344
450 410 a400 -
670 710 a20 -
700 610 a340 b30 tttttttt 456

Команда joinобъединяет file1 и file2 по полям 3 и 2 соответственно. Она используетзамена процессадля обеспечения сортировки обоих файлов по соответствующим ключевым полям. Опция -a 1используется для того, чтобы все строки из file1были напечатаны, даже если они не совпадают со строкой из file2.

К сожалению, joinпомещает поле ключа file1 в начало каждой записи. Это исправлено с помощью awkперемещения полей обратно в их исходный порядок, используя переменную, называемую tвременным держателем для значения $1. Скрипт awk также добавляет завершающий символ тире в поле $4, если между файлами не было совпадений (потому что joinсам он этого не делает).

Наконец, вывод сортируется.

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