合并两个文件并将行转置为列

时间:2018-08-21 12:20:16

标签: awk

比较两个文件中的第一列。如果匹配,则将同一记录的值从FILE2移到FILE1。如果找不到匹配项,请填写“ NA”

FILE1

123 B
124 A
125 N
129 C
134 B
141 T
167 8
179 5

FILE2

123 1 1
123 2 1
124 1 3
124 2 3
129 6 1
129 7 1
134 5 1
134 9 1
167 8 2
167 8 2

所需的输出

123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA

我对丢失的记录使用了此代码,但仍然无法对找到的记录的行进行转位:

awk 'NR==FNR{a[$1]=$2;next;}{print $0 "    " ($1 in a ? a[$1] : "NA")}' FILE2 FILE1

123 B    2
124 A    2
125 N    NA
129 C    7
134 B    9
141 T    NA
167 8    8
179 5    NA

预先感谢

3 个答案:

答案 0 :(得分:1)

根据问题的当前描述和输入示例,此awk代码有效:

 awk 'NR==FNR{a[$1]=$2 FS $3 FS $4;next}{print $0,($1 in a?a[$1]:"NA")}' <(awk 'NR%2{printf "%s",$1 FS $2 FS;next}{print $2,$3}' FILE2) FILE1

为了更好地阅读:

 awk 'NR==FNR{a[$1]=$2 FS $3 FS $4;next}
      {print $0,($1 in a?a[$1]:"NA")}' 
<(awk 'NR%2{printf "%s",$1 FS $2 FS;next}{print $2,$3}' FILE2)  
FILE1

连同您的测试数据:

kent$  head f f2
==> f <==
123 B
124 A
125 N
129 C
134 B
141 T
167 8
179 5

==> f2 <==
123 1 1
123 2 1
124 1 3
124 2 3
129 6 1
129 7 1
134 5 1
134 9 1
167 8 2
167 8 2

kent$  awk 'NR==FNR{a[$1]=$2 FS $3 FS $4;next}{print $0,($1 in a?a[$1]:"NA");}' <(awk 'NR%2{printf "%s",$1 FS $2 FS;next}{print $2,$3}' f2) f
123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA

答案 1 :(得分:1)

请您尝试以下。

awk '
FNR==NR{
  if(++b[$1]==1){
    a[$1]=$2
  }
  else{
    a[$1]=a[$1] OFS $2 OFS $3
  }
  next
}
($1 in a){
  print $1,$2,a[$1]
  next
}
{
  print $0,"NA"
}' Input_file2  Input_file1

输出如下。

123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA

答案 2 :(得分:1)

我假设您想收集file2第二列的列表,但只保留file2第三列的最后一个值。

这里有点perl:

perl -lane '
    if ($. == ++$nr) {
        $x{$F[0]} = $F[1];
    } else {
        push @{ $y{$F[0]} }, $F[1];
        $z{$F[0]} = $F[2];
    }
    close ARGV if eof; # reset $. for new file
    END {
        for $key (sort keys %x) {
            printf "%s %s %s\n", $key, $x{$key},
                (exists $y{$key} ? join(" ", @{$y{$key}}, $z{$key}) : "NA");
        }
    }
' file 1 file2
 
123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA

aswk

gawk '
    NR == FNR {
        x[$1] = $2
        next
    }
    {
        y[$1] = y[$1] $2 OFS
        z[$1] = $3
    }
    END {
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (key in x) {
            printf "%s %s %s\n", key, x[key], (key in y ? y[key] z[key] : "NA")
        }
    }
' file{1,2}

这仅将GNU awk用于PROCINFO变量。如果您不希望出现这种依赖性,只需删除该行并将输出通过管道传递到| sort -k1,1n