2012-07-23 102 views
0

對不起,如果這類問題一直在問,但我在搜索時找不到。比較2個文件並根據條件打印

我有兩個文件A和B.我需要創建一個包含在一個格式的差異文件C如下圖所示:

文件:

foo1 2.1 3 
foo2 3.1 3 
foo3 4.1 3 
foo4 2.1 3 
foo5 3.1 3 

文件B:

foo1 2.0 2.9 
foo2 2.1 3 
foo4 2.1 3 

文件C(OUTPUT):LHS包含來自文件A的值。RHS包含來自文件B的值(或只有xxxx,如果foo不存在)

2.1 3 foo1 2.0 2.9 
3.1 3 foo2 2.1 3 
4.1 3 foo3 xxxxxxxx 
2.1 3 foo4 2.1 3 
3.1 3 foo5 xxxxxxxx 
+0

你嘗試過什麼,什麼是你有問題,這氣味像功課 – 8bitwide 2012-07-23 22:45:32

+0

對不起,我只是改變了形式。我無法繼續將任一類型的值放在同一行上 – user1497417 2012-07-23 22:47:33

+0

您能描述一下輸出的格式應該是什麼嗎?目前還不清楚你要從你的例子中尋找什麼。 – Blckknght 2012-07-23 22:48:04

回答

1

單程使用awk。保存第一個字段fileB作爲散列的一個關鍵字,其餘字段作爲它的值,並且在fileA中的每一行進行比較,如果該關鍵字存在,則打印xxxxxxxx或散列值。

運行下一個命令:

awk ' 
    BEGIN { 
     OFS = "\t"; 
    } 

    FNR == NR { 
     b[ $1 ] = $2 "\t" $3; 
     next; 
    } 

    FNR < NR { 
     str = ($1 in b) ? b[ $1 ] : "xxxxxxxx"; 
     print $2, $3, $1, str; 
    } 
' fileB fileA 

隨着下面的輸出(製表符分隔的字段):

2.1  3  foo1 2.0  2.9 
3.1  3  foo2 2.1  3 
4.1  3  foo3 xxxxxxxx 
2.1  3  foo4 2.1  3 
3.1  3  foo5 xxxxxxxx 
+0

你擊敗了我35秒! +1 – Steve 2012-07-23 23:12:15

+0

完美,謝謝! – user1497417 2012-07-23 23:21:40

+0

@ user1497417:這應該是被接受的答案。 – Steve 2012-07-23 23:24:19

1

一種使用awk方式:

awk 'FNR==NR { array[$1]=$0; next; } { if ($1 in array) print $2, $3, array[$1]; else print $2, $3, $1, "xxxxxxxx"; }' fileB.txt fileA.txt 

在多行上分拆出:

FNR==NR { 
    array[$1]=$0 
    next 
} 

{ 
    if ($1 in array) { 
     print $2, $3, array[$1] 
    } 
    else { 
     print $2, $3, $1, "xxxxxxxx" 
    } 
} 

結果:

2.1 3 foo1 2.0 2.9 
3.1 3 foo2 2.1 3 
4.1 3 foo3 xxxxxxxx 
2.1 3 foo4 2.1 3 
3.1 3 foo5 xxxxxxxx 
+0

完美,謝謝! – user1497417 2012-07-23 23:21:59

+0

快速跟進 - 有沒有辦法在輸出文件中對齊column3?假設我們有foo1,foo2,foobar3,fooo4等格式化會搞砸。 – user1497417 2012-07-24 00:02:22

+0

@ user1497417:請參閱上述Berei的回答和我的評論。 – Steve 2012-07-24 00:40:49

2

通讀兩個文件和將數據存儲在由所述文件的第一fcolumn值鍵控的散列。

use strict; 
use warnings; 

my @files = qw/ FileA.txt FileB.txt /; 
my %data; 

for my $i (0, 1) { 

    open my $fh, '<', $files[$i] or die qq(Unable to open "$files[$i]": $!); 

    while (<$fh>) { 
    s/\s+$//; 
    my ($key, $val) = split ' ', $_, 2; 
    $data{$key}[$i] = $val; 
    } 
} 

for my $key (sort keys %data) { 
    printf "%s %s %s\n", 
     map $_ // 'xxxxxxxx', $data{$key}[0], $key, $data{$key}[1]; 
} 

輸出

2.1 3 foo1 2.0 2.9 
3.1 3 foo2 2.1 3 
4.1 3 foo3 xxxxxxxx 
2.1 3 foo4 2.1 3 
3.1 3 foo5 xxxxxxxx 
+0

感謝您的幫助! – user1497417 2012-07-23 23:39:40

相關問題