Avec des grepimplémentations qui prennent en charge les expressions régulières de type perl (comme pcregrepou GNU ou ast-opengrep -P ), vous pouvez le faire en une seule grepinvocation avec:
grep -P '^(?=.*pat1)(?!.*pat2)|^(?=.*pat2)(?!.*pat1)'
C'est-à-dire trouver les lignes qui correspondent pat1mais paspat2 ou pat2pas pat1.
(?=...)et (?!...)sont respectivement des opérateurs d'anticipation et d'anticipation négative. Donc, techniquement, ce qui précède cherche le début du sujet ( ^) à condition qu'il soit suivi par.*pat1 et non suivi .*pat2, ou le même avec pat1et pat2inversé.
Ce n'est pas optimal pour les lignes qui contiennent les deux modèles car ils seraient ensuite recherchés deux fois. Vous pouvez utiliser à la place des opérateurs Perl plus avancés comme:
grep -P '^(?=.*pat1|())(?(1)(?=.*pat2)|(?!.*pat2))'
(?(1)yespattern|nopattern)correspond à yespatternsi le groupe de capture 1st (vide ()ci-dessus) correspond, et nopatternsinon. Si cela ()correspond, cela signifie pat1ne correspond pas, alors nous recherchonspat2 (regard positif devant), et nous ne cherchons pas pat2 autrement (regard négatif devant).
Avec sed, vous pourriez l'écrire:
sed -ne '/pat1/{/pat2/!p;d;}' -e '/pat2/p'
[a-z][a-z0-9]\(,7\}\(\.[a-z0-9]\{,3\}\)+? (2) Que se passe-t-il si l'un des mots / motifs apparaît plus d'une fois sur une ligne (et que l'autre n'apparaît pas)? Est-ce l'équivalent du mot apparaissant une fois, ou cela compte-t-il comme plusieurs occurrences?