2012-05-02 23 views
100

Bir syslog dosyasına karşı denetlemek için regex kalıplarının bir listesini grep'a geçiriyorum. Genellikle bir IP adresi ve kayıt girişini eşleştirirler;Grep regex Dize içeren NOT

grep "1\.2\.3\.4.*Has exploded" syslog.log 

Öyle bir döngü içinde, geçirerek "1\.2\.3\.4.*Has exploded" parçası gibi kalıplarının sadece bir liste, bu yüzden örneğin "-v" geçemez.

Yukarıdakilerin tersini yapmaya çalışıyorum, belirli bir IP adresiyle bir NOT eşleşme satırı ve hatayı bu yüzden "! 1.2.3.4. * Patladı" 1.2.3.4 dışında bir şey için syslog satırlarıyla eşleşecek ben patladı. I , numaralı bir IP'yi eşleşmemelidir.

StackOverflor'da benzer iletiler görmekteyim ancak grep ile çalışamayacağı göründüğüm regex desenlerini kullanıyorlar. Herkes grep için bir çalışma örneği sunabilir mi lütfen?

GÜNCELLEME: Böyle bir komut dosyasında gerçekleşiyor;

patterns[1]="1\.2\.3\.4.*Has exploded" 
patterns[2]="5\.6\.7\.8.*Has died" 
patterns[3]="\!9\.10\.11\.12.*Has exploded" 

for i in {1..3} 
do 
grep "${patterns[$i]}" logfile.log 
done 
+0

aynı olmalıdır Eğer * bazen * Bir desenle eşleşen istiyor istemem ama diğer zamanlarda belli desen * dışında her şeyi * eşleştirmek istiyor musunuz? (Bu garip bir gereklilik gibi görünüyor, ama her neyse). Bu durumda, neden iki farklı desen listesi üzerinde durmuyorsunuz? – beerbajay

+0

Ben regex hakkında çok bilgili değilim; "Exploded" için grep yapmak istemiyorum çünkü bunu her kayıt cihazı hakkında bilmek istemiyorum, bu yüzden bir şekilde "Has Exploded" ve 9.10.11.12 için tek bir açıklamada bulunabilir miyim? – jwbensley

+0

Eğer bir ifadede kesinlikle yapmanız gerekiyorsa, Neil'in de belirttiği gibi, olumsuz bakış açıları gidecektir. Yorumumu orada gör. – beerbajay

cevap

183

grep maçları, grep -v tersini yapar. Eğer gerekirse, genellikle boru kullanmak "maç A B'ye değil":

grep "${PATT}" file | grep -v "${NOTPATT}" 
komutu, böylece Negatif Geriye İlerleme (Perl düzenli ifade) olması -P ile bu çalıştırmak için gereken
+0

Bu, bahsettiğim gibi bir döngünün ortasına giriyor ve ben sadece DESIGN'u grep'e geçiriyorum, bu yüzden bahsettiğim gibi "-v" yi kullanamıyorum. Ben sadece DESENLER listesi ve grep'e geçiyorum. – jwbensley

+1

Gerçekten de -v' kullanabilirsiniz ve bunu bir döngüde kullanabilirsiniz. Belki de sınırlamalarınız hakkında daha spesifik olmanız gerekir, ya da belki de senaryonuzun nasıl çalışması gerektiği konusunda yanlış bir fikre sahipsiniz. Bazı kodları göndermeyi deneyin. – beerbajay

+0

Teşekkürler beerbajay, bazı içerik vermek için orijinal yazıya snipped bir kod ekledim. Şimdi ne demek istediğimi anlıyor musun? – jwbensley

9
(?<!1\.2\.3\.4).*Has exploded 

:

grep -P '(?<!1\.2\.3\.4).*Has exploded' test.log 

Bunu deneyin. 1.2.3.4 tarafından önceden alınıyorsa, çizgiyi yok saymak için negatif görünüm kullanır. Umarım yardımcı olur!

+1

'grep''in aramayı desteklemediğinden eminim. Gnu 'grep' kullanmıyorsanız ve bir PCRE motoru kullanmak için' --P' parametresini kullanın. –

+0

Hayır, grep bu tür bir Regex'i desteklemez; $ grep -P (? <\! 1 \ .2 \ .3 \ .4) test.log -bash: beklenmedik belirtecin yanında sözdizimi hatası '(' – jwbensley

+0

Karakterleri içeriyorsa normal ifadeyi belirtmeniz gerekir. kabuk tarafından yorumlanır – beerbajay

2
patterns[1]="1\.2\.3\.4.*Has exploded" 
patterns[2]="5\.6\.7\.8.*Has died" 
patterns[3]="\!9\.10\.11\.12.*Has exploded" 

for i in {1..3} 
do 
grep "${patterns[$i]}" logfile.log 
done 

egrep "(1\.2\.3\.4.*Has exploded|5\.6\.7\.8.*Has died)" logfile.log | egrep -v "9\.10\.11\.12.*Has exploded"