【问题标题】:How to merge two files based on the first three columns using awk如何使用awk根据前三列合并两个文件
【发布时间】:2013-03-14 20:42:52
【问题描述】:

我想使用前三列作为键将两个文件逐行合并为一个文件。示例:

file1.txt

a b c 1 4 7
x y z 2 5 8
p q r 3 6 9

file2.txt

p q r 11
a b c 12
x y z 13

以上两个文件我想要的输出是:

a b c 1 4 7 12
x y z 2 5 8 13
p q r 3 6 9 11

每个文件中的列数不是固定的,它可能因行而异。另外,我在每个文件中有超过 27K 行。

它们没有排序。他们唯一的问题是两个文件的前三个字段是相同的。

【问题讨论】:

  • 我已投票决定关闭此问题,因为它似乎是请求推荐工具或解决方案,而不是请求帮助您自己的代码。这使您的问题与 StackOverflow 无关。如果该评估不正确,并且您确实需要帮助编写自己的代码,那么请add your work so far to your question,我将撤回我的近距离投票。

标签: awk


【解决方案1】:

您也可以使用join,它需要排序输入并且前三个字段被合并。下面的示例对每个文件进行排序并让sed 合并和分隔字段:

join <(sort file1.txt | sed 's/ /-/; s/ /-/') \
     <(sort file2.txt | sed 's/ /-/; s/ /-/') |
sed 's/-/ /; s/-/ /'

输出:

a b c 1 4 7 12
p q r 3 6 9 11
x y z 2 5 8 13

【讨论】:

    【解决方案2】:

    加入字段数可变的前三个字段(四个或更多)

    {
        # get the forth field until the last
        for (i=4;i<=NF;i++)
            f=f$i" "
    
        # concat fields
        arr[$1OFS$2OFS$3]=arr[$1OFS$2OFS$3]f;
        # reset field string
        f=""    
    }    
    END {
        for (key in arr)
            print key, arr[key]    
    }
    

    运行方式:

    $ awk -f script.awk file1 file2
    a b c 1 4 7 12 
    p q r 3 6 9 11 
    x y z 2 5 8 13 
    

    【讨论】:

      【解决方案3】:

      试试这个:

       awk 'NR==FNR{a[$1$2$3]=$4;next}$1$2$3 in a{print $0, a[$1$2$3]}' file2 file1 
      

      【讨论】:

      • 这假定正好有 4 列。它还假设连接前三列会产生一个唯一键(对于示例输入为 true,但对于真实文件可能不是 true)。
      • @OpenSauce OP 知道真实文件的格式。如果 OP 有这个要求,我可以更改代码
      • 确实,这部分很容易修复,但我想指出以防 OP 不知道。但更大的问题是“每个文件中的列数不固定,可能因行而异”。您只在数组中保存$4,但我认为您需要从$4 循环到NF
      • $4 列在哪个文件中?同时?如果我有 N 列,我该怎么做?非常感谢。
      【解决方案4】:

      如果列的长度不同,您可以尝试使用SUBSEP

      awk 'NR==FNR{A[$1,$2,$3]=$4; next}($1,$2,$3) in A{print $0, A[$1,$2,$3]}' file2 file1
      

      对于 file1 中的不同列和已排序的输出,请尝试:

      awk '{$1=$1; i=$1 FS $2 FS $3 FS; sub(i,x)} NR==FNR{A[i]=$0; next}i in A{print i $0, A[i]}' file2 file1 | sort
      

      【讨论】:

      • file2 有 7 个固定列,但 file1 可以有 3 个或更多。如果它适用于具有 3 列的 file1 也可以。我希望它们以它们在 file1 中的方式排序。非常感谢。
      猜你喜欢
      • 2019-06-14
      • 2020-07-07
      • 1970-01-01
      • 2011-07-24
      • 2015-11-07
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多