J'essaie de comprendre la syntaxe correcte pour trouver deux chaînes, la totalité de chaque chaîne, n'importe où (ne doit pas être proche de l'autre) dans un fichier. Donc tout fichier qui a à la fois foo
et dire le numéro 321
, ne doit pas être seul et peut être une sous-chaîne devrait correspondre. J'ai essayé ce qui suit sans beaucoup de chance:
grep 'foo\|321' *
grep 'foo|321'
Devrait être un peu plus rapide parce que la deuxième grep
peut fonctionner sur une liste de fichiers.
grep -lZ 'foo' * | xargs -0 grep -l '321'
find
est plus utile si vous souhaitez rechercher des répertoires récursifs (dans ce cas, perdez le -mindepth
et -maxdepth
options.
find . -mindepth 1 -maxdepth 1 -type f -exec grep -q 'foo' {} \; -exec grep -l '321' {} +
Vous pouvez le faire avec un script court:
for FILE in *
do
grep -q foo $FILE && grep -q 321 $FILE && echo $FILE
done
Vous pouvez également le faire sur une ligne:
for FILE in *; do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE; done
grep
retourne 0 (vrai) s'il a trouvé la chaîne et le &&
Séparer les commandes signifie que le second fonctionnera que si le premier était vrai. Les -q
Option garantit que grep
ne produit rien.
L'écho ne fonctionnera que si les deux chaînes ont été trouvées dans le même fichier.
J'ai pensé à une autre façon de le faire. De cette façon sera probablement plus efficace si les fichiers en question sont supérieurs à ceux installés RAM car il n'a que grep
via chaque fichier une fois.
for FILE in *
do
test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE
done
et la version one-line:
for FILE in *; do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE; done
Étrange. Pour moi, les deux variantes travaillent (Grep (GNU Grep) 2.13):
grep 'foo\|321'
grep -E 'foo|321'
éditer 1 - Afficher les fichiers avec les deux matchs uniquement
Les for file in *
Réponse fonctionne mais peut devenir un cauchemar de performance (pour de grandes quantités de fichiers): au moins deux processus par fichier. Ceci est plus rapide (dans le GNU World):
find . -type f -print0 | xargs -0 -r grep --files-with-matches --null -- string1 |
xargs -0 -r grep --files-with-matches -- string2
string1 devrait être celui qui entraîne moins de correspondances.
Fondamentalement, pour trouver tous les fichiers, y compris une chaîne particulière dans un répertoire, vous pouvez utiliser:
grep -lir "pattern" /path/to/the/dir
-l
: pour que cette numérisation s'arrête sur le premier match-i
: ignorer les distinctions de cas dans le motif et les fichiers d'entrée-r
: Rechercher tous les fichiers sous répertoire, récursivementPour rechercher deux modèles, essayez ceci:
grep -lr "321" $(grep -lr "foo" /path/to/the/dir)