2013-08-07 126 views
1

我有2個選項卡分隔的文件,如下所示。基於另一個文件從文件中刪除行

第一個文件: -

raj krishna 2345  19041884 
dev sri  1573  13894083 
dev ravi  1232  54445434 

第二個文件: -

dev sri  1573  42334334 
kar ham  3214  45354354 

我想刪除第一個文件匹配第二個文件中的前3場的任何線路。所以,刪除後的輸出第一個文件應該如下所示。

raj krishna 2345  19041884 
dev ravi  1232  54445434 

任何人都可以告訴我如何在perl或shell腳本中實現此目的。

感謝

回答

1

這使得:

$ awk 'NR == FNR{a[$3];next} !($3 in a)' file2 file1 
raj krishna 2345  19041884 
dev ravi  1232  54445434 

它首先保存文件2的第3場。然後打印沒有第三個字段的行或file1。其基於two-file processing

+0

感謝您的回覆。以上僅使用第三場。如果我想一起使用第一,第二和第三個字段來刪除線條,我如何更改上面的腳本? – Dev

+0

@srikanth你可以改變每個'$ 3'爲'$ 1,$ 2,$ 3'。例如,'{a [$ 1,$ 2,$ 3]; next}'。 – fedorqui

1

Perl解決方案。我把它打包成一個測試,所以你可以...測試它。

#!/usr/bin/perl 

use strict; 
use warnings; 

use autodie qw(open); 

use Test::More tests => 1; 

# I initialize the data within the test 
# the real code would skip this, and open the real files instead 

my $file1="raj krishna 2345 19041884 
dev sri 1573 13894083 
dev ravi 1232 54445434 
"; 

my $file2="dev sri 1573 42334334 
kar ham 3214 45354354 
"; 

my $expected="raj krishna 2345 19041884 
dev ravi 1232 54445434 
"; 

my $file_out; 

open(my $in1, '<', \$file1); # read from a string 
open(my $in2, '<', \$file2); 
open(my $out, '>', \$file_out); # write to a string 

# below is the real code  

# load the list of "records" to remove 
# for each line take the first 3 fields (anything except a tab followed by a tab, 3 times) 
my %to_remove= map { line_to_key($_) => 1 } <$in2>; 

while(my $line=<$in1>) 
    { print {$out} $line unless $to_remove{line_to_key($line)}; } 

close $out; 

# test whether we got what we wanted 
is($file_out, $expected, 'basic test'); 

# the "key": split on tab, then join the first 3 fields, again tab separated 
sub line_to_key 
    { my($line)= @_; 
    my @fields= split /\t/, $line; 
    my $key= join "\t", @fields[0..2]; 
    return $key; 
    } 
相關問題