J'essaie de construire une recherche grep qui recherche un terme mais exclut les lignes qui ont un deuxième terme. Je voulais utiliser plusieurs -e "pattern"
options mais cela n'a pas fonctionné.
Voici un exemple de commande que j'ai essayée et le message d'erreur qu'elle a généré.
grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
Il me semble que le -v
s'applique à tous les termes / modèles de recherche. Comme cela s'exécute, mais ne comprend pas search term
dans les résultats.
grep -i -E "search term" -ve "exclude term"
Réponses:
Pour et les expressions avec grep, vous avez besoin de deux invocations:
Si les termes que vous recherchez ne sont pas des expressions régulières, utilisez une correspondance de chaîne fixe (
-F
) qui est plus rapide:la source
À moins d'invoquer grep deux fois, il n'y a qu'une seule façon de penser à cela. Il s'agit d' expressions régulières compatibles Perl (PCRE) et de quelques assertions de regard plutôt hacky .
Pour rechercher foo en excluant les correspondances contenant une barre , vous pouvez utiliser:
Voici comment cela fonctionne:
(?!bar)
correspond à tout ce qui ne barre pas sans consommer les caractères de la chaîne..
Consomme ensuite un seul personnage.^((?!bar).)*
répète ce qui précède du début de la chaîne (^
) à la fin de celle-ci ($
). Il échouera s'ilbar
est rencontré à un moment donné, car(?!bar)
ne correspondra pas.(?=^((?!bar).)*$)
s'assure que la chaîne correspond au modèle précédent, sans consommer de caractères de la chaîne.foo
recherche foo comme d'habitude.J'ai trouvé ce hack dans l' expression régulière pour faire correspondre une chaîne ne contenant pas de mot? . Dans la réponse de Bart Kiers , vous pouvez trouver une explication beaucoup plus détaillée du fonctionnement de l' anticipation négative.
la source
Si vous voulez faire cela en un seul passage, vous pouvez utiliser awk au lieu de grep.
Format:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
Exemples:
echo "hello there" | awk '/hello/ && !/there/'
Ne renvoie rien.
echo "hello thre" | awk '/hello/ && !/there/'
Retours: bonjour trois
echo "hllo there" | awk '/hello/ && !/there/'
Ne renvoie rien.
Pour plusieurs modèles, vous pouvez utiliser des parenthèses pour les regrouper.
Exemples:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
Retours: bonjour trois
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
Retours: salut trois
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
Ne renvoie rien.
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
Ne renvoie rien.
la source
ls --color=always | awk '/hello/ && !/goodbye/'
grep -R
dans plusieurs fichiers de code en utilisant la ligne de commande Ubuntu.D'après mes expériences, cela ne fait pas beaucoup de différence si vous dirigez vos termes d'exclusion via
grep
oused
. Sed a d'autres fonctionnalités utiles de remplacement de texte que j'utilise souvent pour mieux filtrer la sortie des fichiers journaux. Je vais donc utiliser sed car je combine un certain nombre de filtres sur sed.la source
grep -F
au lieu degrep -E
et ne l'utilisez pas-i
si vous n'en avez pas besoin.sed
;)