我想根据第一列中的信息组合两个文件。
$ cat file1
gnl_1045_ 2 -0.74
gnl_1045_ 2 -0.74
gnl_1046_ 10 0.996904
gnl_1046_ 10 6.904
$ cat file2
gnl_100_ 2 0.42
gnl_100_ 2 0.42
gnl_1025_ 2 0.825
gnl_1025_ 2 0.825
gnl_1046_ 7 4.598512
gnl_1046_ 7 0.4598512
预期输出
gnl_1046_ 10 0.996904 gnl_1046_ 7 4.598512
gnl_1046_ 10 6.904 gnl_1046_ 7 0.4598512
考虑到我之前的问题(join 2 files based on fields in a columns),我对'awk'代码非常肯定:
awk -F "\t" 'NR==FNR{a[$1]=$0; next}$1 in a{print a[$1],$0}' file1 file2
但它无法正常工作,因为它正确打印'file2'但是'file1'它始终只打印公共字段的第一行:
gnl_1046_ 10 0.996904 gnl_1046_ 7 4.598512
gnl_1046_ 10 0.996904 gnl_1046_ 7 0.4598512
我真的不明白我的错误在哪里。 有什么建议吗? 谢谢!
答案 0 :(得分:3)
由于您的1美元不是唯一的,您需要计算每个的出现次数:
$ awk 'NR==FNR{a[$1,++f1[$1]]=$0; next} ($1,++f2[$1]) in a{print a[$1,f2[$1]],$0}' file1 file2
gnl_1046_ 10 0.996904 gnl_1046_ 7 4.598512
gnl_1046_ 10 6.904 gnl_1046_ 7 0.4598512
根据需要将FS和/或OFS更改为标签。
答案 1 :(得分:0)
这里是我的解决方案:
awk 'NR==FNR{i[$1,FNR]=$0;d[$1];n=FNR;next}
$1 in d{for(x=1;x<=n;x++)if(i[$1,x]){
print i[$1,x], $0;delete i[$1,x];break}
}' file1 file2
好吧我没有把<tab>
放在输入文件中,所以你可以稍微调整一下,空格为sep,输出上面的行:
gnl_1046_ 10 0.996904 gnl_1046_ 7 4.598512
gnl_1046_ 10 6.904 gnl_1046_ 7 0.4598512
诀窍是我维护了一个二维数组i(x,y)
,以便在file1中保存相同$ 1的行,并在一个匹配后,删除带有i(x, min(y))
的元素
使用gawk 4测试代码。