2012-10-08 50 views
1

我有兩個文件合併2個文件基於AWK最後colums

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 

我想結合基於這2個文件最後一列(文件1的5列文件2的3列)用awk

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 
+2

你嘗試過這麼遠嗎?你能解釋一個專欄是什麼,而不是期待我們破譯它嗎? – Steve

+0

+1,這實際上是一個有趣的問題。 file2是abit tricky ..在列3兩個相同的「a」。^ _^ – Kent

回答

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

+0

謝謝親愛的肯特:) – mohammad

+0

它工作正常,但因爲我是awk的新手,請你告訴我什麼「if(x〜」^ 「$ 5)」在做什麼?數組a [$ 3「_」NR]的含義是什麼? – mohammad

+0

@mohammadreshad'〜'操作正在做正則表達式匹配。 '[$ 3'_「NR]'聲明一個數組來存儲file2數據。 – Kent

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 
+0

它給了我「致命的錯誤:試圖在標量上下文中使用數組'''! – mohammad

+0

@mohammadreshad:你使用哪個版本的'awk'? – Birei

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