【问题标题】:How to merge two files with different fields based on one matching columns?如何根据一个匹配列合并具有不同字段的两个文件?
【发布时间】:2017-09-21 13:31:36
【问题描述】:

我有如下两个文件,我想根据通用 ID 将它们合并到一个文件中:

文件1:

ARS     8.0   8.0
BBL     1.1   1.2
CCL     1.9   1.8

文件2:

ARS     2.3   2.4
ARS     2.6   2.4
ARS     2.5   2.3
BBL     1.9   1.8
EDE     1.4   1.6

期望的输出:

ARS     8.0   8.0    ARS     2.3   2.4
ARS     8.0   8.0    ARS     2.6   2.4   
ARS     8.0   8.0    ARS     2.5   2.3
BBL     1.1   1.2    BBL     1.9   1.8
CCL     1.9   1.8    NA
NA                   EDE     1.4   1.6

【问题讨论】:

  • 这些是制表符分隔的字段还是固定宽度或一些空白字符或其他什么?
  • Linux - join 2 CSV files的可能重复
  • 它们都是制表符。
  • ARS 能否像在 file2 中一样多次出现在 file1 中?如果是这样,请在您的示例中包含类似的案例。
  • JNevil,那不一样

标签: linux awk


【解决方案1】:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
FNR==1 {
    na = $0
    gsub("[^"FS"]","",na)
    nas[++numFiles] = "NA" na
}
NR==FNR { file1[$1] = $0; next }
$1 in file1 { print file1[$1], $0 }
{ file2[$1] = $0 }
END {
    for (key in file1) {
        if ( !(key in file2) ) {
            print file1[key], nas[2]
        }
    }
    for (key in file2) {
        if ( !(key in file1) ) {
            print nas[1], file2[key]
        }
    }
}

.

$ awk -f tst.awk file1 file2
ARS     8.0     8.0     ARS     2.3     2.4
ARS     8.0     8.0     ARS     2.6     2.4
ARS     8.0     8.0     ARS     2.5     2.3
BBL     1.1     1.2     BBL     1.9     1.8
CCL     1.9     1.8     NA
NA                      EDE     1.4     1.6

可以通过多种方式对其进行优化,使其不将两个文件的全部内容存储在数组中,但我喜欢上述的简单性和对称性,如果由于大量输入文件而证明有必要,以后进行优化是微不足道的。

【讨论】:

  • ^1 喜欢你使用gsub的方式
【解决方案2】:

您能否尝试关注并让我知道这是否对您有帮助。(我最后保留了 NA 的订单,只让我知道这是否对您有帮助)。 在这里也添加非单线形式的解决方案。

awk '
FNR==NR{
  a[$1]=$0;
  next
}
($1 in a){
  print a[$1],$0;
  b[$1];
  next
}
{
  print "NA\t",$0       
}
END{
  for(i in b){
    delete a[i]
};
  for(j in a){
  print a[j],"\tNA"
}
}
' file1  file2

输出如下。

ARS     8.0   8.0 ARS     2.3   2.4
ARS     8.0   8.0 ARS     2.6   2.4
ARS     8.0   8.0 ARS     2.5   2.3
BBL     1.1   1.2 BBL     1.9   1.8
NA   EDE     1.4   1.6
CCL     1.9   1.8   NA

【讨论】:

  • 感谢 RavinderSingh 第二个工作但我希望 NA 在右侧列中识别它属于哪个文件,所以如果 ID 仅来自文件 1,则 NA 应该出现在输出的右侧。 (看看我的问题)。此处 EDE 应出现在右侧,NA 应出现在左侧,而 CCL 则相反。
  • @Behmah,现在请检查我编辑的解决方案并告诉我。
  • 它没有改变:(
  • 当我运行我的代码时,我得到的输出与我在帖子中提到的相同,如果你运行的是完全相同的代码,请告诉我?
  • 我很抱歉 Ed,我真的忽略了它,我现在用输出编辑了我的代码(特别是 NA 的地方)
【解决方案3】:

有一个合并文件的工具

join -a 1 -a 2 -e NA t24.in1 t24.in2  -o 1.1,1.2,1.3,2.1,2.2,2.3

输出:

ARS     8.0     8.0     ARS     2.3     2.4
ARS     8.0     8.0     ARS     2.6     2.4
ARS     8.0     8.0     ARS     2.5     2.3
BBL     1.1     1.2     BBL     1.9     1.8
CCL     1.9     1.8     NA      NA      NA
NA      NA      NA      EDE     1.4     1.6

【讨论】:

    猜你喜欢
    • 2019-06-28
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多