Dengan grep
implementasi yang mendukung ekspresi reguler perl-like (seperti pcregrep
atau GNU atau ast-open grep -P
), Anda dapat melakukannya dalam satu grep
permintaan dengan:
grep -P '^(?=.*pat1)(?!.*pat2)|^(?=.*pat2)(?!.*pat1)'
Yaitu menemukan garis yang cocok pat1
tetapi tidak pat2
, atau pat2
tidak pat1
.
(?=...)
dan (?!...)
masing-masing melihat ke depan dan operator melihat ke depan negatif. Jadi secara teknis, pencarian di atas untuk awal subjek ( ^
) asalkan diikuti .*pat1
dan tidak diikuti .*pat2
, atau sama dengan pat1
dan pat2
terbalik.
Itu suboptimal untuk garis yang mengandung kedua pola karena mereka kemudian akan dicari dua kali. Anda bisa menggunakan operator perl yang lebih canggih seperti:
grep -P '^(?=.*pat1|())(?(1)(?=.*pat2)|(?!.*pat2))'
(?(1)yespattern|nopattern)
cocok dengan yespattern
jika grup penangkap 1
st (kosong di ()
atas) cocok, dan nopattern
sebaliknya. Jika itu ()
cocok, itu berarti pat1
tidak cocok, jadi kami mencari pat2
(melihat ke depan positif), dan kami mencari tidak pat2
sebaliknya (melihat ke depan negatif).
Dengan sed
, Anda bisa menulisnya:
sed -ne '/pat1/{/pat2/!p;d;}' -e '/pat2/p'
[a-z][a-z0-9]\(,7\}\(\.[a-z0-9]\{,3\}\)+
? (2) Bagaimana jika salah satu kata / pola muncul lebih dari satu kali dalam satu baris (dan yang lainnya tidak muncul)? Apakah itu setara dengan kata yang muncul sekali, atau apakah itu dihitung sebagai beberapa kejadian?