Присоединяйтесь, заполняя недостающие ключевые значения

Присоединяйтесь, заполняя недостающие ключевые значения

У меня есть два файла, в которых в качестве первого поля используется значение первичного ключа, а в качестве остальных полей — соответствующие значения. Некоторые значения первичного ключа отсутствуют в одном из них, но присутствуют в другом, и наоборот:

$ cat jointest1.txt jointest2.txt  
a 1  
b 2  
d 4  
e 5    

a 10  
b 11  
c 12  
d 13  

Я ожидаю вывод, который объединяет эти файлы в соответствии с первичным ключом, либо заменяя отсутствующие значения, либо нет, например:

$ joinmerge  jointest1.txt jointest2.txt   
a 1 10  
b 2 11  
c - 12  
d 4 13  
e 5 -

Возможность замены отсутствующих значений дефисами или чем-то еще является необязательной.

Я попробовал join, но мне говорят, что мои файлы отсортированы неправильно:

$ join jointest1.txt jointest2.txt   
a 1 10  
b 2 11  
join: file 2 is not in sorted order  
d 4 13  

Какую команду мне следует использовать вместо этого?

решение1

Попробуйте следующее:

> join -e- -a1 -a2 jointest1 -o 0 1.1 1.2 2.1 2.2 jointest2
a a 1 a 10
b b 2 b 11
c - - c 12
d d 4 d 13
e e 5 - -

или

> join -e- -a1 -a2 jointest1 -o 0 1.2 2.2 jointest2
a 1 10
b 2 11
c - 12
d 4 13
e 5 -

Я не уверен, возможно ли/как можно добиться того же самого без опции -o. Опция -o говорит: сначала вывести поле join, затем поле № 2 из файла 1, затем поле 2 из файла 2. Немного грустно, что нужно знать формат файлов, чтобы заставить работать пустые поля.

решение2

Какую реализацию joinвы используете? С помощью join (GNU coreutils) 5.97я могу использовать

[0 1021] ~/temp/jointest % join -a1 -a2 jointest1.txt jointest2.txt
a 1 10
b 2 11
c 12
d 4 13
e 5 

и "простое" соединение тоже работает (но пропускает c и e). Есть опция, -eкоторая предположительно позволяет вам выбирать маркер для пустых полей, но, похоже, она сломана в моей версии и заполняет только случай e, а не случай c.

решение3

Я написал инструмент Perl именно для этой проблемы «ключ-значение»:

Сопоставление правильных рядов: любое количество файлов. Он также доступен черезGitHub.

Чтобы выполнить его, введите:

merge -k -e "-" jointest1.txt jointest2.txt

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