1

私は2つのファイルを持っています

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 を使用して、これら 2 つのファイル ベースの最後の列 (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 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

于 2012-10-08T13:49:55.990 に答える
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 に答える
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 に答える