我有两个文件,其主键值作为第一个字段,相应的值作为其余字段,其中一个文件中缺少一些主键值,但在另一个文件中存在,反之亦然:
$ 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 选项表示:首先打印连接字段,然后打印字段号。文件 1 中的 2,然后文件 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