将2个文件与基于AWK的最后一列合并

时间:2012-10-08 13:27:37

标签: awk

我有两个文件

file1
-------------------------------
1      a      t      p      b
2      b      c      f      a
3      d      y      u      b
2      b      c      f      a
2      u      g      t      c
2      b      j      h      c

file2
--------------------------------
1   a   b
2   p   c
3   n   a
4   4   a

我希望使用awk结合这两个基于最后一列的文件(file1的第5列和file2的第3列)

result
----------------------------------------------
1      a      t      p     1   a   b
2      b      c      f     3   n   a
2      b      c      f     4   4   a
3      d      y      u     1   a   b
2      b      c      f     3   n   a
2      b      c      f     4   4   a
2      u      g      t     2   p   c
2      b      j      h     2   p   c

3 个答案:

答案 0 :(得分:1)

在一开始,我没有在file2中看到重复的“a”,我认为它将通过正常的数组匹配来解决。 ......现在可以了。

awk onliner:

 awk 'NR==FNR{a[$3"_"NR]=$0;next;}{for(x in a){if(x~"^"$5) print $1,$2,$3,$4,a[x];}}' f2.txt f1.txt

<强>测试

kent$  head *.txt  
==> f1.txt <==
1      a      t      p      b
2      b      c      f      a
3      d      y      u      b
2      b      c      f      a
2      u      g      t      c
2      b      j      h      c

==> f2.txt <==
1   a   b
2   p   c
3   n   a
4   4   a

kent$  awk 'NR==FNR{a[$3"_"NR]=$0;next;}{for(x in a){if(x~"^"$5) print $1,$2,$3,$4,a[x];}}' f2.txt f1.txt 
1 a t p 1   a   b
2 b c f 3   n   a
2 b c f 4   4   a
3 d y u 1   a   b
2 b c f 3   n   a
2 b c f 4   4   a
2 u g t 2   p   c
2 b j h 2   p   c

请注意,输出格式并不性感,但如果将其输送到column -t

则可以接受

答案 1 :(得分:0)

假设文件没有标题的其他方式:

awk '
    FNR == NR {
        f2[ $NF ] = f2[ $NF ] ? f2[ $NF ] SUBSEP $0 : $0;
        next;
    }

    FNR < NR {
        if ( $NF in f2 ) {
            split( f2[ $NF ], a, SUBSEP );
            len = length( a );
            for ( i = 1; i <= len; i++ ) {
                $NF = a[ i ];       
            }
        }
        printf "%s\n", $0;
    }
' file2 file1 | column -t

它产生:

1  a  t  p  1  a  b
2  b  c  f  3  n  a
2  b  c  f  4  4  a
3  d  y  u  1  a  b
2  b  c  f  3  n  a
2  b  c  f  4  4  a
2  u  g  t  2  p  c
2  b  j  h  2  p  c

答案 2 :(得分:0)

支持任意数据结构的语言(列表列表)更容易一些。这是红宝石

# read "file2" and group by the last field
file2 = File .foreach('file2') .map(&:split) .group_by {|fields| fields[-1]}

# process file1
File .foreach('file1') .map(&:split) .each do |fields|
  file2[fields[-1]] .each do |fields2|
    puts (fields[0..-2] + fields2).join(" ")
  end 
end

输出

1 a t p 1 a b
2 b c f 3 n a
2 b c f 4 4 a
3 d y u 1 a b
2 b c f 3 n a
2 b c f 4 4 a
2 u g t 2 p c
2 b j h 2 p c