2014-06-20 42 views
11

Yaygın olmayan bazı satırları olan iki dosyam yok.Iki dosya arasında ortak satırları sıralamadan nasıl kaldırılır?

sort -u file1.txt > file1_sorted.txt 
sort -u file2.txt > file2_sorted.txt 

comm -23 file1_sorted.txt file2_sorted.txt > file_final.txt 

Çıktı:

file1.txt

Z 
B 
A 
H 
L 

file2.txt

S 
L 
W 
Q 
A 

ben ortak çizgileri kaldırmak için kullanıyorum yolu şudur

B 
H 
Z 

Sorun file1.txt sırasını tutmak istiyoruz ki, demek:

İstenilen çıktı: Ben tought

Z 
B 
H 

bir çözüm dosya2'nin tüm satırları okumak için bir döngü yapıyor txt ve:

sed -i '/^${line_file2}$/d' file1.txt 

Ancak dosyalar büyükse performans azalır.

  • Fikrim hoşunuza gitti mi?
  • Bunu yapmak için başka seçeneğiniz var mı? (Invert için -v, dosya için -f)

cevap

12

grep veya awk: Biraz Perl yazdım

awk 'NR==FNR{a[$0]=1;next}!a[$0]' file2 file1 
+0

'a [0 $] = 7' Neden yediye eşittir? Teşekkürler! :) – harrison4

+2

@JohnDoe sadece sıfır olmayan bir sayıya ihtiyacımız var, 7 ve 1'in hiçbir farkı yok. Eğer kendinizi rahat hissettiriyorsa 1'e dönüştürüyorum. :-) – Kent

+0

Evet, şimdi daha iyi hissediyorum. :) – harrison4

10

sadece grep kullanabilirsiniz. input2 tüm doğruları eşleşmeyen input1 gelen grep hatları:

grep -vf input2 input1 

verir:

Z 
B 
H 
+4

'-F -w veya -x' seçeneği ile daha iyi olur mu? Örneğin. alt yazı kutusu. – Kent

3

bu tür bir şey için kullanıyorum. Bu Ne istediğine daha fazlasını yapabilir ama aynı zamanda ne gerek yapabilirsiniz: Senin durumunda

#!/usr/bin/env perl -w 
use strict; 
use Getopt::Std; 
my %opts; 
getopts('hvfcmdk:', \%opts); 
my $missing=$opts{m}||undef; 
my $column=$opts{k}||undef; 
my $common=$opts{c}||undef; 
my $verbose=$opts{v}||undef; 
my $fast=$opts{f}||undef; 
my $dupes=$opts{d}||undef; 
$missing=1 unless $common || $dupes;; 
&usage() unless $ARGV[1]; 
&usage() if $opts{h}; 
my (%found,%k,%fields); 
if ($column) { 
    die("The -k option only works in fast (-f) mode\n") unless $fast; 
    $column--; ## So I don't need to count from 0 
} 

open(my $F1,"$ARGV[0]")||die("Cannot open $ARGV[0]: $!\n"); 
while(<$F1>){ 
    chomp; 
    if ($fast){ 
    my @aa=split(/\s+/,$_); 
    $k{$aa[0]}++; 
     $found{$aa[0]}++; 
    } 
    else { 
    $k{$_}++; 
     $found{$_}++; 
    } 
} 
close($F1); 
my $n=0; 
open(F2,"$ARGV[1]")||die("Cannot open $ARGV[1]: $!\n"); 
my $size=0; 
if($verbose){ 
    while(<F2>){ 
     $size++; 
    } 
} 
close(F2); 
open(F2,"$ARGV[1]")||die("Cannot open $ARGV[1]: $!\n"); 

while(<F2>){ 
    next if /^\s+$/; 
    $n++; 
    chomp; 
    print STDERR "." if $verbose && $n % 10==0; 
    print STDERR "[$n of $size lines]\n" if $verbose && $n % 800==0; 
    if($fast){ 
     my @aa=split(/\s+/,$_); 
     $k{$aa[0]}++ if defined($k{$aa[0]}); 
     $fields{$aa[0]}=\@aa if $column; 
    } 
    else{ 
     my @keys=keys(%k); 
     foreach my $key(keys(%found)){ 
      if (/\Q$key/){ 
      $k{$key}++ ; 
      $found{$key}=undef unless $dupes; 
      } 
     } 
    } 
} 
close(F2); 
print STDERR "[$n of $size lines]\n" if $verbose; 

if ($column) { 
    $missing && do map{my @[email protected]{$fields{$_}}; print "$aa[$column]\n" unless $k{$_}>1}keys(%k); 
    $common && do map{my @[email protected]{$fields{$_}}; print "$aa[$column]\n" if $k{$_}>1}keys(%k); 
    $dupes && do map{my @[email protected]{$fields{$_}}; print "$aa[$column]\n" if $k{$_}>2}keys(%k); 
} 
else { 
    $missing && do map{print "$_\n" unless $k{$_}>1}keys(%k); 
    $common && do map{print "$_\n" if $k{$_}>1}keys(%k); 
    $dupes && do map{print "$_\n" if $k{$_}>2}keys(%k); 
} 
sub usage{ 
    print STDERR <<EndOfHelp; 

    USAGE: compare_lists.pl FILE1 FILE2 

     This script will compare FILE1 and FILE2, searching for the 
     contents of FILE1 in FILE2 (and NOT vice versa). FILE one must 
     be one search pattern per line, the search pattern need only be 
     contained within one of the lines of FILE2. 

    OPTIONS: 
     -c : Print patterns COMMON to both files 
     -f : Search only the first characters of each line of FILE2 
     for the search pattern given in FILE1 
     -d : Print duplicate entries  
     -m : Print patterns MISSING in FILE2 (default) 
     -h : Print this help and exit 
EndOfHelp 
     exit(0); 
} 

, sen -f seçenek sadece karşılaştırmak yapar

list_compare.pl -cf file1.txt file2.txt 

olarak aday olacağını 2. dosyanın (beyaz boşluk ile tanımlanmış) ilk kelimesi ve büyük ölçüde işleri hızlandırır. Tüm çizgiyi karşılaştırmak için -f'u kaldırın.

İlgili konular