Вкладка завершена в терминале bash / gnome, вместо этого открывается emacs

С grepреализациями, которые поддерживают perl -например, регулярные выражения (например pcregrepили GNU или ast -open grep -P), вы можете сделать это за один grepвызов с помощью:

grep -P '^(?=.*pat1)(?!.*pat2)|^(?=.*pat2)(?!.*pat1)'

То есть найти строки, которые соответствуют pat1, но не pat2, или pat2, но не pat1.

(?=...)и (?!...)— соответственно операторы просмотра вперед и отрицательного просмотра вперед. Таким образом, технически вышеприведенное ищет начало субъекта (^), если за ним следует .*pat1, а не следует .*pat2, или то же самое с pat1и pat2в обратном порядке.

Это неоптимально для строк, содержащих оба шаблона, поскольку тогда их будут искать дважды. Вместо этого вы можете использовать более продвинутые операторы perl, такие как:

grep -P '^(?=.*pat1|())(?(1)(?=.*pat2)|(?!.*pat2))'

(?(1)yespattern|nopattern)совпадает с yespattern, если совпадает1st группа захвата (пустая ()выше ), и nopatternв противном случае. Если это ()совпадает, это означает, что pat1не совпадает, поэтому мы ищемpat2(положительный просмотр вперед ), и мы ищем , а не pat2, иначе (отрицательный просмотр вперед ).

С помощью sedвы можете написать это:

sed -ne '/pat1/{/pat2/!p;d;}' -e '/pat2/p'
2
26.01.2021, 16:11
0 ответов

Теги

Похожие вопросы