2010-10-16 8 views
5

J'ai 2 fichiers, le premier contient les éléments suivants:AWK/BASH: comment faire correspondre un champ dans un fichier d'un champ dans un autre?

... 
John Allen Smith II 16 555-555-5555 10/24/2010 
John Allen Smith II 3 555-555-5555 10/24/2010 
John Allen Smith II 17 555-555-5555 10/24/2010 
John Doe 16 555-555-5555 10/24/2010 
Jane Smith 16 555-555-5555 9/16/2010 
Jane Smith 00 555-555-5555 10/24/2010 
... 

et le second fichier est une liste de noms donc ...

... 
John Allen Smith II 
John Doe 
Jane Smith 
... 

Est-il possible d'utiliser awk (ou autre bash commande) pour imprimer les lignes dans le premier fichier qui correspondent à un nom dans le deuxième fichier (les noms peuvent répéter dans le premier fichier)

Bonus? Existe-t-il un moyen facile de supprimer ces lignes répétées/dupliquées dans le premier fichier?

Merci beaucoup,

Tomek

+0

S'il y a 2 lignes égales, il en reste une. Est-ce votre définition de «supprimer» les lignes dupliquées? – ghostdog74

Répondre

3

awk

#! /bin/bash 
awk 'FNR==NR{!a[$0]++;next }{ b[$0]++ } 
END{ 
    for(i in a){ 
    for(k in b){ 
     if (a[i]==1 && i ~ k) { print i } 
    } 
    } 
}' file1 file2 
1

Vous pouvez utiliser grep comme:

grep -f file2 file1 # file2 is the file with the names. 

L'option -f de grep obtient le motif à rechercher dans le fichier.

Pour supprimer les doublons exacts de la sortie, vous pouvez utiliser sort comme:

grep -f file2 file1 | sort -u 
+0

J'ai essayé d'utiliser la commande mais j'ai obtenu ce qui suit, "grep: Unmatched [ou [^", j'ai alors essayé d'utiliser -F pour forcer mais il n'y avait pas de sortie? Cette commande utilise-t-elle tout le fichier file2 dans un modèle de recherche pour essayer de correspondre à file1? – Tomek

+0

J'ai spécifié le drapeau -F faux (j'ai remplacé -f avec -F) de sorte que la commande finale grep -f fichier2 -F fichier1 a fonctionné. Merci pour l'aide. – Tomek

+0

pour l'unique, je cherchais à supprimer les lignes de fichier1 qui ont seulement les noms répétés (les autres colonnes ont des données différentes) – Tomek

1

expansion sur la réponse codaddict:

grep -f file2 file1 | sort | uniq 

cela supprimera les lignes qui sont exactement les mêmes, mais l'effet secondaire (qui peut être indésirable) est que votre dat l'afile sera maintenant trié. Il faut également que les lignes soient exactement le même, ce qui n'est pas le cas dans vos données d'exemple. Les noms sont les mêmes, mais les données après ces mêmes noms sont différentes. uniq peut prendre une option de champ ou de nombre de caractères, mais cela ne fonctionnera pas sur vos données car vos noms ont une longueur variable et un nombre variable de champs. Si vous connaissez vos champs de données sont toujours les 3 derniers champs sur une ligne, vous pouvez le faire:

grep -f file2 file1 | sort | rev | uniq -f 3 | rev 

votre sortie sera seulement un de chaque nom, mais lequel? le lexicographiquement le plus bas parce qu'il a été trié (sort est nécessaire pour que uniq fonctionne correctement). Si vous ne voulez pas le trier en premier, ou si vous devez faire attention aux lignes qui sont supprimées, alors une solution awk ou perl ou ruby ​​ou python fonctionnera probablement mieux en utilisant des tableaux associatifs.

+0

Oui, c'est exactement mon problème. Les noms peuvent être de longueur variable et les données après le nom sont différentes. Je cherche juste à obtenir la première occurrence de dire John Allen Smith II. Je vais regarder dans quelques tableaux associatifs avec awk. Merci pour l'info. – Tomek