ฉันวางใจอย่างมากกับ pcregrep แต่ด้วย grep ที่ใหม่กว่าคุณไม่จำเป็นต้องติดตั้ง pcregrep สำหรับคุณสมบัติมากมาย grep -P
ใช้เพียงแค่
ในตัวอย่างของคำถามของ OP ฉันคิดว่าตัวเลือกต่อไปนี้ทำงานได้ดีโดยการจับคู่ที่ดีที่สุดที่สองฉันเข้าใจคำถาม:
grep -Pzo "abc(.|\n)*efg" /tmp/tes*
grep -Pzl "abc(.|\n)*efg" /tmp/tes*
ฉันคัดลอกข้อความเป็น / tmp / test1 และลบ 'g' และบันทึกเป็น / tmp / test2 นี่คือผลลัพธ์ที่แสดงว่ารายการแรกแสดงสตริงที่ตรงกันและรายการที่สองแสดงเฉพาะชื่อไฟล์ (ทั่วไป -o คือแสดงการจับคู่และทั่วไป -l คือแสดงเฉพาะชื่อไฟล์) โปรดทราบว่า 'z' เป็นสิ่งจำเป็นสำหรับ multiline และ '(. | \ n)' หมายถึงการจับคู่ 'สิ่งอื่นที่ไม่ใช่ newline' หรือ 'newline' - เช่นอะไร:
user@host:~$ grep -Pzo "abc(.|\n)*efg" /tmp/tes*
/tmp/test1:abc blah
blah blah..
blah blah..
blah blah..
blah efg
user@host:~$ grep -Pzl "abc(.|\n)*efg" /tmp/tes*
/tmp/test1
หากต้องการตรวจสอบว่ารุ่นของคุณใหม่เพียงพอหรือไม่ให้เรียกใช้man grep
และดูว่ามีบางอย่างที่คล้ายกันนี้ปรากฏขึ้นที่ด้านบนหรือไม่:
-P, --perl-regexp
Interpret PATTERN as a Perl regular expression (PCRE, see
below). This is highly experimental and grep -P may warn of
unimplemented features.
นั่นคือจาก GNU grep 2.10