2010-09-21 3 views
0

Ma solution actuelle:quelle est la meilleure façon de trouver un sous-ensemble d'une liste avec grep?

#!/bin/sh 
while read file2 
do 
grep $file2 file1 
done 

le contenu de fichier1 sera quelque chose comme:

atlanta,blue,20090805 
newyork,blue,20090805 
washington,blue,20090805 
dallas,blue,20090805 
jacksonville,blue,20090805 

le contenu de fichier2 sera quelque chose comme:

newyork 
dallas 
jacksonville 

et la sortie désirée un fichier serait quelque chose comme:

newyork,blue,20090805 
dallas,blue,20090805 
jacksonville,blue,20090805 

Lorsque vous cherchez un sous-ensemble d'une grande liste basée sur les noms d'une deuxième liste, quelle est la meilleure façon de faire quelque chose comme ça? Toute recommandation serait appréciée!

Merci,

+0

si vous utilisez grep comme cela, assurez-vous que vos données ne sont pas NewYork, dalla ou à jacksonville sur la première ligne, sauf le début de la ligne. – ghostdog74

Répondre

1

... Qu'en est-

egrep -f file2 file1 

pour votre exemple le cas, il devrait fonctionner comme votre boucle ne; et il devrait s'appliquer à la même gamme de cas que votre description verbale et votre boucle font (un "nom" par ligne dans le fichier "deuxième liste", c'est-à-dire aucune ponctuation qui pourrait mal interpréter).

+0

egrep est obsolète. 'grep -E' – ghostdog74

0

Ce triche car il est perl, mais ce sont deux one-liners:

#!/bin/bash 
REGEX=`perl -lne 'push(@x,$_);END{print join("|",@x)."\n";}' < file2` 
perl -ne 'print $_ if (/\b(?:$ENV{REGEX})\b/o);' < file1 

La première ligne crée une liste d'options de la forme: NewYork | dallas | jacksonville et stocke dans la variable d'environnement REGEX . La deuxième ligne imprimera alors toute ligne correspondant (newyork | dallas | jacksonville). Les morceaux de la regex ici:

  • Le \ b signifie que cela ne fonctionnera que si la ville est entourée de limites de mots. Cela signifie que "york" ne correspondra pas à "newyork".
  • Le?: Signifie que perl n'essaiera pas de capturer le groupe, ce qui conduit à de meilleures performances.
  • $ ENV {REGEX} prend un paramètre de l'environnement.
  • Sans le/o, perl essayera de réévaluer la variable $ ENV sur chaque ligne, ce qui conduira à de mauvaises performances.
0
$ awk -F"," 'FNR==NR{a[$1]}NR>FNR && ($1 in a)' file2 file1 
newyork,blue,20090805 
dallas,blue,20090805 
jacksonville,blue,20090805 
+0

merci pour les réponses! – gfrench

Questions connexes