web-dev-qa-db-fra.com

grep - chaîne d'exclusion qui n'est pas une sous-chaîne d'une chaîne

J'explique mon problème sur Ubuntu 16.04 avec l'exemple suivant: Le fichier est:

# cat file
aaa
aaaxxx
aaaxxx*aaa
aaa=aaaxxx
bbbaaaccc
aaaddd/aaaxxx

Je souhaite afficher toutes les lignes contenant aaa mais pas dans la combinaison niquement de aaaxxx. Je veux une sortie comme celle-ci:

# grep SOMETHING-HERE file …
aaa
aaaxxx*aaa (second aaa is the hit)
aaa=aaaxxx (first aaa is the hit)
bbbaaaccc (aaa in any other combination but not aaaxxx)
aaaddd/aaaxxx (similar to above)

J'ai essayé des choses comme grep -v aaaxxx file | grep aaa qui ont pour résultat:

aaa
bbbaaaccc

ou

# egrep -P '(?<!aaaxxx )aaa' file
grep: die angegebenen Suchmuster stehen in Konflikt zueinander (the pattern are in contradiction)

Y a-t-il une possibilité (simple)? Bien sûr, il n’est pas nécessaire que ce soit grep. Merci

4
musbach

Il est simple d'utiliser un opérateur lookahead de style Perl - disponible en mode PCRE (Perl Compatible Regular Expression) de grep à l'aide du commutateur -P:

$ grep -P 'aaa(?!xxx)' file
aaa
aaaxxx*aaaaaa=aaaxxx
bbbaaaccc
aaaddd/aaaxxx

(Le format en gras dans la sortie indique les parties correspondantes mises en surbrillance par grep)


Bien que le préfixe de longueur nulle soit pratique, vous pouvez obtenir le même résultat en utilisant la syntaxe GNU Expression régulière étendue (ERE), par exemple en faisant correspondre aaa suivi de 2 x au maximum. caractères suivis d'un caractère non -x ou d'une fin de ligne, c'est-à-dire.

grep -E 'aaax{0,2}([^x]|$)' file

ou même en utilisant la syntaxe GNU de base des expressions régulières (BRE)

grep 'aaax\{0,2\}\([^x]\|$\)' file

qui correspondent comme

aaa
aaaxxx*aaaaaa=aaaxxx
bbbaaaccc
aaaddd/aaaxxx
6
steeldriver