J'essaie d'utiliser grep
pour faire correspondre les lignes qui contiennent deux chaînes différentes. J'ai essayé ce qui suit mais cela correspond aux lignes qui contiennent soit string1 ou string2 qui ne correspondent pas à ce que je veux.
grep 'string1\|string2' filename
Alors, comment puis-je faire correspondre grep
uniquement les lignes contenant les deux chaînes ?
Réponses:
Vous pouvez utiliser
grep 'string1' filename | grep 'string2'
Ou,
grep 'string1.*string2\|string2.*string1' filename
la source
grep -e "string1" -e "string2"
Je pense que c'est ce que vous cherchiez:
Je pense que des réponses comme celle-ci:
correspond uniquement au cas où les deux sont présents, pas l'un ou l'autre ou les deux.
la source
grep -e "string1" -e "string2" filename
la même chose?How do I match lines that contains *both* strings?
Pour rechercher des fichiers contenant tous les mots dans n'importe quel ordre, n'importe où:
Le premier grep lance une recherche récursive (
r
), ignorant la casse (i
) et listant (imprimant) le nom des fichiers qui correspondent (l
) pour un terme ('action'
avec les guillemets simples) se trouvant n'importe où dans le fichier.Les greps suivants recherchent les autres termes, conservent l'insensibilité à la casse et répertorient les fichiers correspondants.
La liste finale des fichiers que vous obtiendrez sera celle qui contient ces termes, dans n'importe quel ordre n'importe où dans le fichier.
la source
grep -ril 'foo' | xargs -d '\n' grep -il 'bar'
Si vous avez un
grep
avec une-P
option pour uneperl
expression rationnelle limitée , vous pouvez utiliserce qui a l'avantage de travailler avec des chaînes qui se chevauchent. C'est un peu plus simple d'utiliser
perl
asgrep
, car vous pouvez spécifier la logique et plus directement:la source
Votre méthode était presque bonne, il ne manquait que le -w
la source
grep -V
es.grep -w 'regexp1\|regexp2' filename
L'
|
opérateur dans une expression régulière signifie ou. C'est-à-dire que string1 ou string2 correspondra. Vous pourriez faire:qui dirigera les résultats de la première commande vers le deuxième grep. Cela ne devrait vous donner que des lignes qui correspondent aux deux.
la source
Vous pouvez essayer quelque chose comme ceci:
la source
Et comme les gens ont suggéré perl et python, et des scripts shell compliqués, voici une approche awk simple :
Après avoir regardé les commentaires de la réponse acceptée: non, cela ne fait pas plusieurs lignes; mais ce n'est pas non plus ce que l'auteur de la question a demandé.
la source
N'essayez pas d'utiliser grep pour cela, utilisez plutôt awk. Pour faire correspondre 2 expressions rationnelles R1 et R2 dans grep, vous penseriez que ce serait:
alors qu'en awk ce serait:
mais que se passe-t-il si
R2
chevauche ou est un sous-ensemble deR1
? Cette commande grep ne fonctionnerait tout simplement pas alors que la commande awk le ferait. Disons que vous voulez trouver des lignes qui contiennentthe
etheat
:Il faudrait utiliser 2 greps et un pipe pour ça:
et bien sûr, si vous aviez réellement demandé qu'ils soient séparés, vous pouvez toujours écrire dans awk la même expression régulière que celle utilisée dans grep et il existe des solutions alternatives à awk qui n'impliquent pas de répéter les expressions rationnelles dans chaque séquence possible.
Mis à part cela, que se passe-t-il si vous souhaitez étendre votre solution pour correspondre à 3 regexps R1, R2 et R3. En grep, ce serait l'un de ces mauvais choix:
alors qu'en awk, ce serait concis, évident, simple, efficace:
Maintenant, que se passe-t-il si vous vouliez réellement faire correspondre les chaînes littérales S1 et S2 au lieu des expressions rationnelles R1 et R2? Vous ne pouvez tout simplement pas faire cela en un seul appel à grep, vous devez soit écrire du code pour échapper à toutes les métachars RE avant d'appeler grep:
ou encore utiliser 2 greps et un pipe:
qui sont encore de mauvais choix alors qu'avec awk vous utilisez simplement un opérateur de chaîne au lieu de l'opérateur regexp:
Maintenant, que se passe-t-il si vous souhaitez faire correspondre 2 expressions rationnelles dans un paragraphe plutôt qu'une ligne? Ne peut pas être fait dans grep, trivial dans awk:
Que diriez-vous de l'ensemble d'un fichier? Encore une fois, cela ne peut pas être fait en grep et trivial en awk (cette fois, j'utilise GNU awk pour RS multi-caractères pour la concision, mais ce n'est pas beaucoup plus de code dans n'importe quel awk ou vous pouvez choisir un contrôle-caractère que vous ne savez pas être en entrée pour que le RS fasse de même):
Donc - si vous voulez trouver plusieurs expressions rationnelles ou chaînes dans une ligne ou un paragraphe ou un fichier, n'utilisez pas grep, utilisez awk.
la source
awk '/R1/ && /R2/'
-il insensible à la casse?awk -v IGNORECASE=1 '/R1/ && /R2/'
et avec n'importe quel awkawk '{x=toupper($0)} x~/R1/ && x~/R2/'
GNU grep version 3.1
la source
Lignes trouvées commençant seulement par 6 espaces et se terminant par:
la source
Disons que nous devons trouver le nombre de mots multiples dans un fichier de test de fichier. Il y a deux façons de procéder
1) Utilisez la commande grep avec le modèle de correspondance d'expression régulière
2) Utilisez la commande egrep
Avec egrep, vous n'avez pas à vous soucier de l'expression et juste séparer les mots par un séparateur de tuyau.
la source
git grep
Voici la syntaxe à utiliser
git grep
avec plusieurs modèles:Vous pouvez également combiner des modèles avec des expressions booléennes telles que
--and
,--or
et--not
.Cherchez
man git-grep
de l'aide.Autres paramètres à considérer:
Pour modifier le type de modèle, vous pouvez également utiliser
-G
/--basic-regexp
(par défaut),-F
/--fixed-strings
,-E
/--extended-regexp
,-P
/--perl-regexp
,-f file
et d' autres.En relation:
Pour l' opération OR , voir:
la source
Placez les chaînes que vous souhaitez grep dans un fichier
Recherchez ensuite à l'aide de -f
la source
obtiendra la ligne avec string1 et string2 dans n'importe quel ordre
la source
Cela fonctionne pour une correspondance exacte des mots et des mots insensibles à la casse, pour que -i soit utilisé
la source
pour une correspondance multiligne:
ou
nous avons juste besoin de supprimer le caractère de nouvelle ligne et cela fonctionne!
la source
Vous devriez avoir
grep
comme ça:la source
Je rencontre souvent le même problème que le vôtre, et je viens d'écrire un morceau de script:
Usage:
Vous pouvez le mettre en .bashrc si vous le souhaitez.
la source
Lorsque les deux chaînes sont en séquence, mettez un motif entre les deux sur la
grep
commande:Exemple si les lignes suivantes sont contenues dans un fichier nommé
Dockerfile
:Pour obtenir la ligne qui contient les chaînes:
FROM python
etas build-python
puis utilisez:Ensuite, la sortie n'affichera que la ligne qui contient les deux chaînes :
la source
ripgrep
Voici l'exemple utilisant
rg
:C'est l'un des outils les plus rapides, car il est construit sur le moteur regex de Rust qui utilise des automates finis, SIMD et des optimisations littérales agressives pour rendre la recherche très rapide.
Utilisez-le, surtout lorsque vous travaillez avec des données volumineuses.
Voir également la demande de fonctionnalité associée au GH-875 .
la source
string2
apparaît avantstring1
. La solution la plus simple à ce problème estrg string1 file.txt | rg string2
.