Yanıtlar:
Bundan başka bir araç grepgitmek için yoludur.
Perl kullanarak, örneğin, komut olacaktır:
perl -ne 'print if /pattern1/ xor /pattern2/'
perl -nestdin'in her satırı üzerinde verilen komutu çalıştırır; bu durumda eğer eşleşirse satırı basar, /pattern1/ xor /pattern2/diğer bir deyişle bir deseni eşleştirir, diğerini seçmez (özel veya).
Bu, desen için her iki sırada da çalışır ve birden fazla çağrı yapılmasından daha iyi bir performansa sahip olmalı grepve daha az daktilo yazması gerekir.
Veya, daha kısa, awk ile:
awk 'xor(/pattern1/,/pattern2/)'
veya sahip olmayan awk sürümleri için xor:
awk '/pattern1/+/pattern2/==1`
xorAwk yalnızca GNU Awk'ta kullanılabilir mi?
/pattern1/+/pattern2/==1İr ile değiştirebilirsiniz xor.
\b) kalıpların içine koyabilirsiniz , yani \bword\b.
İle deneyin egrep
egrep 'pattern1|pattern2' file | grep -v -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
grep -e foo -e bar | grep -v -e 'foo.*bar' -e 'bar.*foo'
Direct invocation as either egrep or fgrep is deprecated- tercih edingrep -E
-fve -eseçeneklere sahip olduğundan bahsetmektedir . egrepfgrep
grep(yani destekler -F, -E, -e, -fPOSIX gerektirir) içinde /usr/xpg4/bin. Yardımcı programlar /binantika olanlardır.
İle grepuygulamalara destek düzenli ifadeler perl benzeri (gibi o pcregrepya GNU veya ast-açık grep -P), bir de bunu yapabiliyor grepile çağırma:
grep -P '^(?=.*pat1)(?!.*pat2)|^(?=.*pat2)(?!.*pat1)'
Yani çizgileri o maç bulmak pat1değil pat2, ya pat2ama pat1.
(?=...)ve (?!...)sırasıyla ileriye bakmak ve negatif görünüm öncesinde operatörleri vardır. Bu yüzden teknik olarak, yukarıdakiler ^takip ettiği .*pat1ve takip etmediği .*pat2veya takip ettiği pat1ve pat2tersine çevrildiği takdirde konunun ( ) başlangıcını arar .
Bu, her iki deseni içeren satırlar için daha düşüktür ve iki kez aranır. Bunun yerine daha gelişmiş perl operatörleri kullanabilirsiniz:
grep -P '^(?=.*pat1|())(?(1)(?=.*pat2)|(?!.*pat2))'
(?(1)yespattern|nopattern)eşleşiyor yespatternise 1st yakalama grubu (boş ()üzeri) eşleştirilmiş ve nopatternaksi. O takdirde ()kibrit, araçlarının pat1biz bakmak eşleşmedi, böylece pat2(öncesinde pozitif görünüm) ve biz bakmak değil pat2 aksi (negatif görünüm yeşil ışık).
Bununla birlikte sedyazabilirsiniz:
sed -ne '/pat1/{/pat2/!p;d;}' -e '/pat2/p'
grep: the -P option only supports a single pattern, en azından erişimime sahip olduğum her sistemde başarısız oluyor . Yine de ikinci çözümünüz için +1.
grep. pcregrepve ast-açık grep bu sorunu yok. Ben birden yerini ettik -eo GNU çalışmalıdır böylece, münavebe RE operatörüyle grepde şimdiki gibi.
Boolean terimleriyle, olarak yazılabilecek A xor B'yi arıyorsunuz
(A ve B değil)
veya
(B ve A değil)
Sorunuzun, eşleşen satırlar gösterildiği sürece çıktının sırası ile ilgilenmediğinizden bahsetmediği göz önüne alındığında, A xor B'nin Boolean genişlemesi, grep'te oldukça basittir:
$ cat << EOF > foo
> a b
> a
> b
> c a
> c b
> b a
> b c
> EOF
$ grep -w 'a' foo | grep -vw 'b'; grep -w 'b' foo | grep -vw 'a';
a
c a
b
c b
b c
sort | uniq.
Aşağıdaki örnek için:
# Patterns:
# apple
# pear
# Example line
line="a_apple_apple_pear_a"
Bu ile tamamen yapılabilir grep -E, uniqve wc.
# Grep for regex pattern, sort as unique, and count the number of lines
result=$(grep -oE 'apple|pear' <<< $line | sort -u | wc -l)
Eğer grepPerl Düzenli ifadeler derlendi sonra yerine kadar boruya gerek son görüldüğü üzerine eşleşebilir uniq:
# Grep for regex pattern and count the number of lines
result=$(grep -oP '(apple(?!.*apple)|pear(?!.*pear))' <<< $line | wc -l)
Sonuç çıktısı:
# Only one of the words exists if the result is < 2
((result > 0)) &&
if (($result < 2)); then
echo Only one word matched
else
echo Both words matched
fi
Bir astar:
(($(grep -oP '(apple(?!.*apple)|pear(?!.*pear))' <<< $line | wc -l) == 1)) && echo Only one word matched
Deseni kodlamak istemezseniz, değişken bir eleman grubuyla birleştirilmesi bir fonksiyonla otomatikleştirilebilir.
Bu, aynı zamanda, doğal olarak Bash'de borular veya ek işlemler içermeyen bir işlev olarak da yapılabilir, ancak daha fazla ilgili olacaktır ve muhtemelen sorunuzun kapsamı dışındadır.
Big apple\nve pear-shaped\nçıktı her iki satırı da içermelidir. Çözümünüz 2 sayısını alacaktır; Uzun versiyon “Her iki kelimeyle eşleşiyor” şeklinde rapor eder (yanlış sorunun cevabıdır) ve kısa versiyon hiç bir şey söylemezdi. (3) Bir öneri: -oburada kullanmak gerçekten kötü bir fikir, çünkü eşleşmeleri içeren satırları gizliyor, bu yüzden her iki kelimenin de aynı satırda göründüğünü göremiyorsunuz. … (Devam ediyor)
uniq/ kullanmanız sort -ubu soruya gerçekten yararlı bir cevap vermez. Ancak, yapsalar bile, yine de kötü bir cevap olurdu, çünkü soruyu cevaplamaya nasıl katkıda bulunduklarını açıklamıyorsunuz . ( İyi bir açıklama örneği için Stéphane Chazelas'ın cevabına bakınız .)
[a-z][a-z0-9]\(,7\}\(\.[a-z0-9]\{,3\}\)+? (2) Eğer kelimelerden / kalıplardan biri bir satırda bir defadan fazla görünürse (diğeri görünmüyorsa)? Bu, bir kez görünen kelimeye eşdeğer mi, yoksa çoklu tekrarlamalar olarak mı sayılıyor?