ด้วย GNU grep
:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
คำอธิบาย:
-o
=> พิมพ์เฉพาะสิ่งที่คุณจับคู่
-P
=> ใช้นิพจน์ปกติสไตล์ Perl
- regex บอกว่าจับคู่ 0 กับ
$N
ตัวอักษรตามด้วยfoo
ตามด้วย 0 ถึง$N
ตัวละคร
หากคุณไม่มี GNU grep
:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
คำอธิบาย:
เนื่องจากเราไม่สามารถพึ่งพาgrep
GNU ได้อีกต่อไปgrep
เราจึงใช้find
การค้นหาไฟล์แบบเรียกซ้ำ (การ-r
กระทำของ GNU grep
) สำหรับแต่ละไฟล์ที่พบเราดำเนินการตัวอย่างโค้ด Perl
สวิตช์ Perl:
-n
อ่านไฟล์ทีละบรรทัด
-l
นำขึ้นบรรทัดใหม่ที่ท้ายบรรทัดแต่ละบรรทัดแล้วนำกลับมาใหม่เมื่อพิมพ์
-e
ถือเป็นสตริงต่อไปนี้เป็นรหัส
Perl grep
ข้อมูลโค้ดจะทำหลักเป็นสิ่งเดียวกับ มันเริ่มต้นด้วยการตั้งค่าตัวแปร$N
ตามจำนวนตัวอักษรบริบทที่คุณต้องการ BEGIN{}
วิธีนี้จะถูกดำเนินการเพียงครั้งเดียวในช่วงเริ่มต้นของการดำเนินการไม่ได้ครั้งเดียวสำหรับสายในไฟล์ทุก
คำสั่งที่ดำเนินการสำหรับแต่ละบรรทัดคือการพิมพ์บรรทัดหากการทดแทน regex ทำงาน
Regex:
- ตรงกับสิ่งเก่า ๆ อย่างเกียจคร้าน1ที่จุดเริ่มต้นของบรรทัด (
^.*?
) ตามด้วย.{0,$N}
ในgrep
กรณีตามด้วยfoo
ตามด้วยอีกอันหนึ่ง.{0,$N}
และในที่สุดก็จับคู่สิ่งเก่า ๆ อย่างเกียจคร้านจนถึงจุดสิ้นสุดของบรรทัด ( .*?$
)
$ARGV:$1
เราทดแทนนี้กับ $ARGV
เป็นตัวแปรเวทมนต์ที่เก็บชื่อไฟล์ปัจจุบันที่กำลังอ่าน $1
เป็นสิ่งที่ parens จับคู่: บริบทในกรณีนี้
- การจับคู่แบบขี้เกียจที่ปลายทั้งสองข้างนั้นเป็นเพราะการจับคู่โลภจะกินตัวละครทั้งหมดก่อน
foo
โดยไม่ล้มเหลวในการจับคู่ (เนื่องจาก.{0,$N}
ได้รับอนุญาตให้จับคู่เป็นศูนย์ครั้ง)
1 นั่นคือไม่ต้องการจับคู่สิ่งใดเลยนอกจากจะทำให้การจับคู่โดยรวมล้มเหลว กล่าวโดยย่อให้จับคู่อักขระน้อยที่สุด