Работа с утилитой join, ошибка join is not sorted (данные файла не отсортированы)

Join – полезная утилита для объединения нескольких текстовых файлов по какому-то общему идентификатору. Название намекает на аналогию с функцией join в SQL.

~$ cat >1
asd 1
bsd 2
csd 3
~$ cat >2
asd test
bsd testtest
csd testtesttest

~$ join 1 2
asd 1 test
bsd 2 testtest
csd 3 testtesttest
Delimeter

join -t”;” – задаем разделитель для csv.

SORT

join и sort обычно используются в паре т.к. столбцы, по которым идет join, должны быть отсортированы в одинаковой последовательности в обоих файлах. В противном случае будет ошибка “join: данные файла не отсортированы” и строки с отличной последовательностью будут потеряны. Опция –nocheck-order позволяет убрать alarm, но строки все равно потеряются.

~$ cat sw
192.168.1.253 1
192.168.128.13 2
192.168.128.17 3
192.168.128.1 4
~$ cat sw2
192.168.1.253 1
192.168.128.1 2
192.168.128.13 3
192.168.128.17 4

~$ join sw sw2
192.168.1.253 1 1
192.168.128.13 2 3
join: sw:4: is not sorted: 192.168.128.1 4
192.168.128.17 3 4
~$ join --nocheck-order sw sw2
192.168.1.253 1 1
192.168.128.13 2 3
192.168.128.17 3 4

В случае сортировки IP и наличия второго столбца обычная сортировка, даже с опцией –n, не поможет:

~$ join <(sort -n sw) <(sort -n sw2) 
192.168.1.253 1 1
join: /dev/fd/63:3: is not sorted: 192.168.128.1 4
192.168.128.13 2 3
192.168.128.17 3 4

Нужно сортировать только по первому столбцу или сразу по всем четырем октетам IP, например:

~$ join <(sort -k1,1 sw) <(sort -k1,1 sw2) 
192.168.1.253 1 1
192.168.128.1 4 2
192.168.128.13 2 3
192.168.128.17 3 4
~$ join <(sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 sw) <(sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 sw2) 
192.168.1.253 1 1
192.168.128.1 4 2
192.168.128.13 2 3
192.168.128.17 3 4
Несколько файлов

Пример join по нескольким файлам:

~$ join <(sort -k1,1 sw) <(sort -k1,1 sw2) | join - <(sort -k1,1 sw3)
192.168.1.253 1 1 44
192.168.128.1 4 2 33
192.168.128.13 2 3 22
192.168.128.17 3 4 11

Leave a Reply