1

我有两个文件

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
4

3 回答 3

1

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

awk 在线用户:

 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

于 2012-10-08T13:49:55.990 回答
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
于 2012-10-08T14:02:57.457 回答
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
于 2012-10-08T15:35:20.580 回答