2013-08-07 4 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 

Это во-первых, сохраняет 3-е поле file2. Затем печатает строки или файл1, не имеющие этого третьего поля.

Он основан на two-file processing.

+0

Спасибо за ваш ответ. В приведенном выше примере используется только 3-е поле. Если я хочу использовать 1-е, 2-е и 3-е поля вместе, чтобы удалить строки, как я могу изменить приведенный выше сценарий? – 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; 
    } 
Смежные вопросы