Grep regex Dize İÇERMEZ


182

grepBir syslog dosyasına karşı kontrol etmek için normal ifade desenleri listesi geçiriyorum. Genellikle bir IP adresi ve günlük girişi ile eşleşirler;

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

Bu sadece bir "1\.2\.3\.4.*Has exploded"döngü içinde geçmekte olduğum kısım gibi desenlerin bir listesi , bu yüzden örneğin "-v" yi geçemiyorum.

Yukarıdakilerin tersini yapmaya çalışırken kafam karıştı, belirli bir IP adresi ve hatayla eşleşmeyen bir NOT eşleşmesi "! . Ben olmalıdır maç DEĞİL bir IP ekleyemeyebiliriz.

StackOverflor üzerinde çeşitli benzer mesajlar gördüm, ancak onlar ile çalışmak gibi olamaz regex desenleri kullanın grep. Herkes greplütfen çalışma örneği verebilir mi?

GÜNCELLEME: Bu böyle bir senaryoda oluyor;

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

Bazen bir deseni eşleştirmek istediğiniz anlamına gelir , ancak diğer zamanlarda belirli bir desen dışındaki her şeyi eşleştirmek ister misiniz ? (bu tuhaf bir gereklilik gibi görünüyor, ama her neyse). Bu durumda, neden iki farklı desen listesini tekrarlamıyorsunuz?
— beerbajay

Regex hakkında çok bilgili değilim; Her kayıt cihazı hakkında bunu bilmek istemediğim için "Exploded Has" için grep istemiyorum, bu yüzden bir şekilde "Exploded Has" ve! 9.10.11.12 için bir şekilde grep?
— jwbensley

Kesinlikle bir ifadede yapmanız gerekiyorsa, Neil'in önerdiği gibi olumsuz bakışlar gitmenin yoludur. Yorumuma bakın.
— beerbajay

@Neil'in cevabına göre PCRE tarzı normal ifade eşleştirmesi ve negatif bir ileriye dönük iddiası patterns[3]="\!9\.10\.11\.12.*Has exploded"kullanın : PCRE'deki değişiklikler patterns[3]="(?<!9\.10\.11\.12).*Has exploded"ve PCRE'deki grep "${patterns[$i]}" logfile.logdeğişiklikler grep -P "${patterns[$i]}" logfile.logvarsayılan olarak daha fazla meta karakter kabul eder, bu nedenle kaçışların bazı eşleşen ifadelerden kaldırılması gerekebilir.
— Codex24

Yanıtlar:


342

grepeşleşir, grep -vtersini yapar. "A ile B'yi eşleştirmeniz" gerekiyorsa, genellikle borular kullanırsınız:

grep "${PATT}" file | grep -v "${NOTPATT}"

Bu, bahsettiğim gibi bir döngünün ortasına gidiyor ve sadece DESEN'i grep'e geçiyorum, böylece bahsettiğim gibi "-v" kullanamıyorum. Ben sadece bir desen listesi döngü ve grep geçiyor.
— jwbensley

1
Gerçekten kullanabilirsiniz -vve bir döngüde kullanabilirsiniz. Belki de sınırlamalarınız hakkında daha spesifik olmanız ya da senaryonuzun nasıl çalışması gerektiği konusunda yanlış bir fikriniz var. Bir kod göndermeyi deneyin.
— beerbajay

Teşekkürler beerbajay, bazı bağlam vermek için orijinal gönderiye kesilmiş bir kod ekledim. Ne demek istediğimi anlıyor musun?
— jwbensley

Bu cevap tamamen doğru değil ama hemen hemen beerbajay yazdınız, döngüyü yeniden düşünmem ve sonunda -v kullanmam gerekiyordu. İşaretçi için teşekkürler;)
— jwbensley

1
Peki ya A B'den oluşuyorsa? Başka bir deyişle, beraber hatları maç ne isterseniz hiçbir A ve AB ile hatlar? Bir boru çalışmaz.
— pawamoy

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

Negatif gözbebeküne (Perl düzenli ifadesi) sahip olmak için bunu -P ile çalıştırmanız gerekir, bu yüzden komut:

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

Bunu dene. Önceden varsa çizgiyi görmezden gelmek için negatif gözetleme kullanır 1.2.3.4. Umarım yardımcı olur!


1
Eminim, grepetrafındaki görüşü desteklemiyor. Gnu grepkullanmadığınızda ve --Pparametreyi bir PCRE motoru kullanması için kullanmadığınız sürece .
— Tim Pietzcker

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

Kabuk tarafından yorumlanacak karakterler içeriyorsa normal ifadeyi alıntılamanız gerekir.
— beerbajay

doğru alıntı: grep -P '(?<!1\.2\.3\.4) Has exploded' test.logLookbehind ifadesinin yalnızca ifadenin eşleşen kısmından hemen önceki karakterlerde çalıştığını unutmayın; bu nedenle adres ve mesaj arasında başka şeyler varsa, örneğin 1.2.3.4 FOO Has explodedbu işe yaramaz.
— beerbajay

@ Timpietzcker, çok dikkatli. Bunu soruya ekleyeceğim. Ayrıca, .*örneğinde de olduğu için olumsuz bir bakıştan sonra bir tane olduğunu lütfen unutmayın, aralarında başka bir metin olabileceğini hayal ediyorum.
— Neil

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

ile aynı olmalı

egrep "(1\.2\.3\.4.*Has exploded|5\.6\.7\.8.*Has died)" logfile.log | egrep -v "9\.10\.11\.12.*Has exploded"    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.