2014-06-20 5 views
1

Ceci est une question de suivi de: Unexpected result comparing values of rows and columns in two text filesComment vérifier si une ligne à partir d'un fichier texte existe dans un autre fichier texte à l'aide awk

J'ai créé une structure pour comparer deux fichiers texte en fonction de leurs lignes et colonnes. Voici les structures de fichier:

file1.txt

Name Col1 Col2 Col3 
----------------------- 
row1 1  4  7   
row2 2  5  8   
row3 3  6  9 

file2.txt

Name Col1 Col2 Col3 
-----------------------   
row1 1  4  7 
row2 2  5  999 

Voici le code que j'ai jusqu'à présent:

dos2unix ravi # 2>/dev/null 
dos2unix ravi2 # 2>/dev/null 

awk '  
    FNR < 2 {next}  # skips first two lines 
    FNR == NR {   
     for (i = 2; i <= NF; i++) { 
      a[i,$1] = $i;    
     }  
     b[$1];    
     next;      
    } 

    ($1 in b) {     # check if row in file2 existed in file1 
     for (i = 2; i <= NF; i++) { 
      if (a[i,$1] == $i) 
       printf("%s->col%d: %s vs %s: Are Equal\n", $1, i-1, a[i,$1], $i); 
      else 
       printf("%s->col%d: %s vs %s: Not Equal\n", $1, i-1, a[i,$1], $i); 
     } 
    } 

    !($1 in b) {     # check if row in file2 doesn't exist in file1. 
     for (i = 2; i <= NF; i++) 
      printf("%s->col%d: %s vs %s: Are Not Equal\n", $1, i-1, "blank", $i); 
    } 

    // pattern needed to check if row in file1 doesn't exist in file2. 

    ' $PWD/file1.txt $PWD/file2.txt 

Quelqu'un at-il conseils, suggestions ou astuces pour avoir un motif dans l'instruction awk pour vérifier si la ligne du fichier 1 n'existe pas fichier2. Voir les exemples de résultats ci-dessous pour comprendre ce que je veux dire. (ie: Fondamentalement, je veux imprimer les valeurs de row3 dans le fichier 1 n'existe pas dans le fichier 2). Merci! Faites-moi savoir si d'autres explications sont nécessaires.

souhaité Sortie:

row2->Col1: 1 vs 1: Equal 
row2->Col2: 4 vs 4: Equal 
row2->Col3: 7 vs 7: Equal 
row1->Col1: 2 vs 2: Equal 
row1->Col2: 5 vs 5: Equal 
row1->Col3: 8 vs 999: Not Equal 
row3->Col1: 3 vs (blank) : Not Equal 
row3->Col2: 6 vs (blank) : Not Equal 
row3->Col3: 9 vs (blank) : Not Equal 

sortie réelle:

row2->Col1: 1 vs 1: Equal 
row2->Col2: 4 vs 4: Equal 
row2->Col3: 7 vs 7: Equal 
row1->Col1: 2 vs 2: Equal 
row1->Col2: 5 vs 5: Equal 
row1->Col3: 8 vs 999: Not Equal 
+0

Vous devriez probablement utiliser un petit script python pour cela, mais qui vient de mes deux cents. –

Répondre

4

Prolonger votre réponse:

$ cat script.awk 
FNR < 2 { next }  # skips first two lines 
FNR == NR { 
    for (i = 2; i <= NF; i++) { a[i,$1] = $i } 
    b[$1]; 
    next; 
} 
($1 in b) {     # check if row in file2 existed in file1 
    for (i = 2; i <= NF; i++) { 
     if (a[i,$1] == $i) 
      printf("%s->col%d: %s vs %s: Are Equal\n", $1, i-1, a[i,$1], $i); 
     else 
      printf("%s->col%d: %s vs %s: Not Equal\n", $1, i-1, a[i,$1], $i); 
    } 
    delete b[$1]; # delete entries which are processed 
} 

END { 
    for (left in b) { # look which didn't match 
     for (i = 2; i <= NF; i++) 
      printf("%s->col%d: %s vs (blank): Not Equal\n", left, i-1, a[i,left]) 
    } 
} 

géré comme:

$ awk -f script.awk file1 file2 
row1->col1: 1 vs 1: Are Equal 
row1->col2: 4 vs 4: Are Equal 
row1->col3: 7 vs 7: Are Equal 
row2->col1: 2 vs 2: Are Equal 
row2->col2: 5 vs 5: Are Equal 
row2->col3: 8 vs 999: Not Equal 
row3->col1: 3 vs (blank): Not Equal 
row3->col2: 6 vs (blank): Not Equal 
row3->col3: 9 vs (blank): Not Equal 
+1

+1 pour passer autant de temps dans ce code long – anubhava

+1

@jaypal J'apprécie le temps que vous avez passé à coder ceci (donc +1) mais il n'imprime toujours pas «row3» pour n'importe quelle colonne. – Alias

+2

@Nosscire Assurez-vous qu'ils n'ont aucun caractère de contrôle. Je viens de tester cela et cela fonctionne très bien avec vos données données. –

1

Si vous savez que chaque ligne « nom » (première colonne) apparaît dans chaque fichier au plus une fois alors vous pourriez delete b[$1] à à la fin du bloc ($1 in b), déplacez le bloc !($1 in b) au-dessus, puis ajoutez un bloc END qui boucle tout ce qui reste dans b et imprime vos lignes.

END { 
    for (r in b) { 
     for (i = 2; i <= NF; i++) { 
      printf("%s->col%d: %s vs %s: Are Not Equal\n", r, i-1, $i, "blank"); 
     } 
    } 
} 
Questions connexes