61 votes

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

J'ai besoin d'une regex à passage unique pour unix grep qui contient, disons alpha, mais ne contient pas beta.

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

1 votes

Veuillez afficher un exemple d'entrée et de sortie attendue. Comment voulez-vous que le paramètre 'y' ne corresponde pas à toutes les lignes sauf 'x' ? Ce qui est une autre façon de dire que vous pouvez vouloir une passe grep 1, mais vous avez probablement besoin d'une passe grep 2 OU awk ou perl script pour une passe unique. Par ailleurs, ce n'est pas mon vote négatif. Peut-être que quelqu'un expliquera pourquoi c'est une mauvaise question ! Bonne chance.

0 votes

Je pense que c'est une question raisonnable à poser (donc +1 de ma part) d'autant plus que je l'ai déjà vue posée auparavant, et que je l'ai même posée moi-même.

0 votes

@shellter : Je connaissais plusieurs façons de le faire en utilisant awk, sed et perl. Même la commande grep peut le faire avec un pipe (j'ai ajouté une ligne d'exemple dans la question). Je voulais juste voir si cela pouvait être fait en une seule fois. Il semble que ce soit possible (réponse de Mr47 ci-dessous) et j'ai pu apprendre le look-ahead et le look-behind en perl. C'est amusant d'apprendre de nouveaux trucs dans n'importe quel langage. Je ne comprends pas pourquoi vous pensez que c'est une mauvaise question. Et j'ai également voté en faveur de votre réponse :)

52voto

nohat Points 2818

Les autres réponses ici montrent quelques façons de contourner différentes variétés d'expressions régulières pour faire cela, bien que je pense que la réponse est, en général, "ne faites pas cela". 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 utilisant la logique booléenne du langage que vous utilisez. Si vous utilisez le grep à l'invite d'un shell unix, il suffit de passer les résultats de l'un à l'autre :

grep "alpha" | grep -v "beta"

J'utilise ce genre de construction tout le temps pour réduire les résultats excessifs de grep . Si vous avez une idée de l'ensemble de résultats qui sera 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'entrée entière.

34voto

shellter Points 15304

Puisque nous postons tous des réponses, voici le résultat en awk ;-)

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

J'espère que cela vous aidera.

0 votes

Il manque un guillemet simple devant l'expression !

2 votes

@KevinDuke : Je pense que j'ai raison, awk peut traiter && d reg-exp maths. merci de regarder ma réponse. Bonne chance à tous.

0 votes

Hmm, je pense que tu as raison aussi, j'aurais juré que ça ne marchait pas l'autre jour. Merci pour votre contribution !

25voto

Mr47 Points 2091

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

0 votes

Je suis presque sûr que POSIX grep ne supporte pas une telle syntaxe !

0 votes

Je ne l'ai pas testé, mais je suis presque sûr que ma version de grep supporte une syntaxe comme celle-ci. Mais je peux me tromper.

3 votes

Pourriez-vous expliquer comment les "(" et les " ?" fonctionnent ici ? Je ne comprends pas pourquoi il y a deux "(" au début.

4voto

Shea Levy Points 1481

Je suis presque sûr que ce n'est pas possible avec de vraies expressions régulières. Le site [^y]*x[^y]* par exemple, correspondrait à yxy, puisque l'astérisque * permet d'obtenir zéro ou plusieurs correspondances non-y.

EDIT :

En fait, ça semble fonctionner : ^[^y]*x[^y]*$ . En gros, cela signifie "correspondre à toute ligne qui commence par zéro ou plus caractères non-y, puis a un x, puis se termine par zéro ou plus caractères non-y".

0voto

sblundy Points 27163

Essayez d'utiliser l'opérateur d'exclusion : [^y]*x[^y]*

1 votes

[^y]* correspond à la chaîne de caractères y car il n'y a aucun caractère non-y dans cette chaîne.

0 votes

Oui, et alors ? Mon exemple est [^y]*x[^y]*.

1 votes

Notez que je réponds à la question au même niveau d'abstraction que la question elle-même.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X