grep regex ไม่ได้มีสตริง


181

ฉันกำลังส่งรายการรูปแบบ regex ไปgrepยังเพื่อตรวจสอบกับไฟล์ syslog พวกเขามักจะตรงกับที่อยู่ IP และบันทึกรายการ;

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

มันเป็นรายการของรูปแบบที่เหมือนกับ"1\.2\.3\.4.*Has exploded"ตอนที่ฉันผ่านเป็นวงดังนั้นฉันไม่สามารถผ่าน "-v" ได้

ฉันสับสนที่พยายามทำผกผันของด้านบนบรรทัดที่ไม่ตรงกับที่อยู่ IP และข้อผิดพลาดบางอย่างดังนั้น "! 1.2.3.4. * มีการระเบิด" จะจับคู่สาย syslog สำหรับสิ่งอื่นที่ไม่ใช่ 1.2.3.4 บอกฉันว่ามันระเบิด . ฉันจะต้องรวม IP เพื่อไม่ให้ตรงกัน

ฉันได้เห็นโพสต์ที่คล้ายกันมากมายใน StackOverflor แต่พวกเขาใช้รูปแบบ regex ที่ฉันไม่สามารถใช้งานgrepได้ ทุกคนสามารถให้ตัวอย่างที่ใช้งานได้เพื่อgrepโปรด

UPDATE: สิ่งนี้เกิดขึ้นในสคริปต์เช่นนี้

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

คุณหมายถึงบางครั้งคุณต้องการจับคู่รูปแบบ แต่บางครั้งคุณต้องการจับคู่ทุกอย่างยกเว้นบางรูปแบบ (ดูเหมือนว่าเป็นข้อกำหนดที่แปลก แต่ไม่ว่าอะไรก็ตาม) ในกรณีนั้นทำไมคุณไม่ทำซ้ำมากกว่าสองรายการรูปแบบที่แตกต่างกัน?
beerbajay

ฉันไม่มีความรู้เกี่ยวกับ regex มากนัก ฉันไม่ต้องการ grep สำหรับ "Has Exploded" เพราะฉันไม่ต้องการที่จะรู้เรื่องนี้เกี่ยวกับอุปกรณ์การบันทึกทุกครั้งดังนั้นฉันสามารถ grep สำหรับ "Has Exploded" และ! 9.10.11.12 ในข้อความเดียวได้ไหม?
jwbensley

หากคุณต้องทำอย่างแน่นอนในหนึ่งแถลงการณ์เชิงลบมองหาเป็นวิธีที่จะไปตามที่นีลแนะนำ ดูความคิดเห็นของฉันที่นั่น
beerbajay

ใช้การจับคู่ regex สไตล์ PCRE และการยืนยันเชิงลบแบบ lookahead ตามคำตอบของ @Neil: patterns[3]="\!9\.10\.11\.12.*Has exploded"การเปลี่ยนแปลง patterns[3]="(?<!9\.10\.11\.12).*Has exploded"และgrep "${patterns[$i]}" logfile.logการเปลี่ยนเป็น grep -P "${patterns[$i]}" logfile.logPCRE จะถือว่า metacharacters มากขึ้นตามค่าเริ่มต้นดังนั้นการหลบหลีกบางอย่างอาจต้องถูกเอาออกจากนิพจน์การจับคู่อื่น ๆ
Codex24

คำตอบ:


341

grepตรงgrep -vกับผกผัน หากคุณต้องการ "จับคู่ A แต่ไม่ใช่ B" คุณมักจะใช้ไพพ์:

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

นี่จะเข้าสู่วงกลางตามที่ฉันพูดถึงและฉันเพิ่งผ่านรูปแบบการ grep ดังนั้นฉันจึงไม่สามารถใช้ "-v" ตามที่ฉันพูดถึง ฉันแค่วนรอบรายการรูปแบบและส่งไปยัง grep
jwbensley

1
คุณสามารถใช้งานได้จริง-vและคุณสามารถใช้มันในการวนซ้ำ บางทีคุณอาจต้องเจาะจงเกี่ยวกับข้อ จำกัด ของคุณหรืออาจเข้าใจผิดว่าสคริปต์ของคุณควรทำงานอย่างไร ลองโพสต์โค้ด
beerbajay

ขอบคุณ beerbajay ฉันได้เพิ่มรหัสที่ถูกโพสต์ไปยังโพสต์ต้นฉบับเพื่อให้บริบท คุณเห็นสิ่งที่ฉันหมายถึงตอนนี้?
jwbensley

คำตอบนี้ไม่ถูกต้องสมบูรณ์ แต่คุณเขียน beerbajay ค่อนข้างมากฉันต้องคิดใหม่วนซ้ำและใช้ -v ในตอนท้าย ขอบคุณสำหรับตัวชี้;)
jwbensley

1
แต่ถ้า A ประกอบด้วย B ล่ะ กล่าวอีกนัยหนึ่งถ้าฉันต้องการจับคู่บรรทัดที่ไม่มี A และบรรทัดกับ AB ท่อจะไม่ทำงาน
pawamoy

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

คุณต้องรันสิ่งนี้ด้วย -P เพื่อให้มี lookbehind เชิงลบ (นิพจน์ปกติ Perl) ดังนั้นคำสั่งคือ:

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

ลองสิ่งนี้ มันใช้ lookbehind 1.2.3.4เชิงลบที่จะไม่สนใจสายถ้ามันถูกนำหน้าโดย หวังว่าจะช่วย!


1
ฉันค่อนข้างแน่ใจว่าgrepไม่สนับสนุนการค้นหา นอกเสียจากคุณกำลังใช้ Gnu grepและใช้--Pพารามิเตอร์เพื่อใช้เป็นเครื่องมือ PCRE
ทิม Pietzcker

ไม่ grep ไม่สนับสนุน Regex ประเภทนี้ $ grep -P (? <\! 1 \ .2 \ .3 \ .4) test.log -bash: ข้อผิดพลาดทางไวยากรณ์ใกล้โทเค็นที่ไม่คาดคิด `('
jwbensley

คุณจะต้องอ้างถึง regex ถ้ามันมีตัวละครที่เชลล์จะตีความ
beerbajay

การอ้างอิงที่ถูกต้อง: grep -P '(?<!1\.2\.3\.4) Has exploded' test.logโปรดทราบว่า lookbehind จะทำงานเฉพาะกับตัวละครที่อยู่ตรงหน้าส่วนที่ตรงกับการแสดงออกดังนั้นหากมีสิ่งอื่น ๆ ระหว่างที่อยู่และข้อความเช่น1.2.3.4 FOO Has explodedนี้จะไม่ทำงาน
beerbajay

@ TimPietzcker ช่างสังเกตมาก ฉันจะเพิ่มเข้าไปในคำถาม นอกจากนี้โปรดทราบว่ามีการมอง.*ในเชิงลบหลังจากตัวอย่างของเขามีมันฉันคิดว่าอาจมีข้อความอื่น ๆ ในระหว่าง
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

ควรเป็นเช่นเดียวกับ

egrep "(1\.2\.3\.4.*Has exploded|5\.6\.7\.8.*Has died)" logfile.log | egrep -v "9\.10\.11\.12.*Has exploded"    
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.