
У меня есть два файла, в которых в качестве первого поля используется значение первичного ключа, а в качестве остальных полей — соответствующие значения. Некоторые значения первичного ключа отсутствуют в одном из них, но присутствуют в другом, и наоборот:
$ 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