将所有文件 2 与列匹配的文件 1 合并

Merge all of file 2 against file 1 where columns match

我在 sas 中有以下代码,我想使用 bash 或 python- linux 机器上的任何东西进行复制。 它根据匹配列 (amer_chr.chr=map.chr) 将两个文件合并在一起 (amer_chr 和地图),但保留两个文件中的行

proc sql;
  create table both_amer_chr. as 
    select amer_chr.* , map.* 
    from amer_chr,map 
    where amer_chr.chr=map.chr
  ;

Amer_chr 长得像

chr score weight
1 1 1235
1 2 1268
1 3 1258
2 1 1267
2 1 2467
3 1 1122
3 4 5634
39 3 1234

地图看起来像

chr snp pos
1 1_123 1234
1 1_213 1456
1 1_435 1678
2 2_122 1763
2 2_321 1987
2 2_379 2003
3 3_013 2000
3 3_184 2008
3 3_398 4929
3 3_518 6512

sas 中的结果 both_amer_chr 如下所示,并且不会包含 amer_chr 的最后一行,因为它的 chr=39 不在文件 2

chr score weight chr snp pos
    1 1 1235 1 1_123 1234
    1 1 1235 11 1_213 1456
    1 1 1235 1 1_435 1678
    1 2 1268 1 1_123 1234
    1 2 1268 1 1_213 1456
    1 2 1268 1 1_435 1678
    1 3 1258 1 1_123 1234
    1 3 1258 1 1_213 1456
    1 3 1258 1 1_435 1678
    2 1 1267 2 2_122 1763
    2 1 1267 2 2_321 1987
    2 1 1267 2 2_379 2003
    2 1 2467 2 2_122 1763
    2 1 2467 2 2_321 1987
    2 1 2467 2 2_379 2003
    3 1 1122 3 3_013 2000
    3 1 1122 3 3_184 2008
    3 1 1122 3 3_398 4929
    3 1 1122 3 3_518 6512
    3 4 5634 3 3_013 2000
    3 4 5634 3 3_184 2008
    3 4 5634 3 3_398 4929
    3 4 5634 3 3_518 6512

基本上加入所有文件 2,其中 chr 列与文件 1 匹配。有没有办法使用 bash 重新创建它,也许是 awk,或者 python 或 perl?

join,基本上

=> 在文件的第一列加入

join amer_chr map

或不默认列 (-j)

join -j 1 amer_chr map

如果你想要两列chr

=> 添加用于选择列顺序的格式选项 (-o)

join -j 1 -o 0,1.2,1.3,2.1,2.2,2.3 amer_chr map

如果您想要文件 amer_chr 中的数据而不是 map

中的数据

=> 添加附加 (-a) 选项和空文本 (-e) 选项

join -j 1 -o 0,1.2,1.3,2.1,2.2,2.3 -a 1 -e "none" amer_chr map

如果您想要文件 map 中的数据而不是 amer_chr

中的数据

=> 添加附加 (-a) 选项和空文本 (-e) 选项,但使用第二个文件

join -j 1 -o 0,1.2,1.3,2.1,2.2,2.3 -a 2 -e "none" amer_chr map

如果您想要文件 amer_chr 中但不在 map 中或文件 map 中但不在 amer_chr

中的数据

=> 添加两次附加 (-a) 选项和空文本 (-e) 选项

join -j 1 -o 0,1.2,1.3,2.1,2.2,2.3 -a 1 -a 2 -e "none" amer_chr map

这可能是您想要执行的操作(取决于您希望如何处理 map 中具有 chr 值但 Amer_chr 中不存在的行),在每个 Unix 机器上使用任何 shell 中的任何 awk,无论输入文件中的行顺序如何,也不管输入文件中存在多少字段:

$ cat tst.awk
NR==FNR {
    vals[,++cnt[]] = [=10=]
    next
}
 in cnt {
    for (i=1; i<=cnt[]; i++) {
        print [=10=], vals[,i]
    }
}

$ awk -f tst.awk map Amer_chr
chr score weight chr snp pos
1 1 1235 1 1_123 1234
1 1 1235 1 1_213 1456
1 1 1235 1 1_435 1678
1 2 1268 1 1_123 1234
1 2 1268 1 1_213 1456
1 2 1268 1 1_435 1678
1 3 1258 1 1_123 1234
1 3 1258 1 1_213 1456
1 3 1258 1 1_435 1678
2 1 1267 2 2_122 1763
2 1 1267 2 2_321 1987
2 1 1267 2 2_379 2003
2 1 2467 2 2_122 1763
2 1 2467 2 2_321 1987
2 1 2467 2 2_379 2003
3 1 1122 3 3_013 2000
3 1 1122 3 3_184 2008
3 1 1122 3 3_398 4929
3 1 1122 3 3_518 6512
3 4 5634 3 3_013 2000
3 4 5634 3 3_184 2008
3 4 5634 3 3_398 4929
3 4 5634 3 3_518 6512