web-dev-qa-db-fra.com

Unix grep regex contenant 'x' mais pas contenant 'y'

J'ai besoin d'un regex en un seul passage pour grep unix qui contient, disons alpha, mais ne contient pas de bêta.

grep 'alpha' <> | grep -v 'beta'
43
Wilderness

^((?!beta).)*alpha((?!beta).)*$ ferait l'affaire, je pense.

18
Mr47

Les autres réponses ici montrent des façons de contourner différentes variétés de regex pour le faire, bien que je pense qu’il est avéré que la réponse est, en général, «ne faites pas ça». De telles expressions régulières sont beaucoup plus difficiles à lire et probablement plus lentes à exécuter que la simple combinaison de deux expressions régulières en utilisant la logique booléenne de la langue que vous utilisez. Si vous utilisez la commande grep à l'invite du shell unix, transmettez simplement les résultats de l'un à l'autre:

grep "alpha" | grep -v "beta"

J'utilise ce type de construction tout le temps pour vaincre les résultats excessifs de grep. Si vous avez une idée du jeu de résultats le plus petit, placez-le en premier dans le pipeline pour obtenir les meilleures performances, car la deuxième commande ne doit traiter que la sortie de la première, et non l'intégralité de l'entrée.

35
nohat

Bien, comme nous publions tous des réponses, le voici dans awk ;-)

awk '/x/ && !/y/' infile

J'espère que ça aide.

25
shellter

Je suis sûr que ce n'est pas possible avec de vraies expressions régulières. L'exemple [^y]*x[^y]* correspondrait à yxy, car le * autorise zéro ou plusieurs correspondances autres que y.

MODIFIER:

En fait, cela semble fonctionner: ^[^y]*x[^y]*$. Cela signifie fondamentalement "correspond à n'importe quelle ligne qui commence par zéro ou plusieurs caractères non-y, a ensuite un x, puis se termine avec zéro ou plusieurs caractères non-y".

3
Shea Levy

Essayez d’utiliser l’opérateur excludes: [^y]*x[^y]*

0
sblundy