นี่คือวิธีการจับคู่สายอักขระหลายตัวแบบไม่โลภอย่างแน่นหนาโดยใช้ sed ช่วยบอกว่าคุณต้องการที่จะเปลี่ยนทุกfoo...barการ<foo...bar>ดังนั้นสำหรับตัวอย่างเช่นการป้อนข้อมูลนี้:
$ cat file
ABC foo DEF bar GHI foo KLM bar NOP foo QRS bar TUV
ควรเป็นผลลัพธ์นี้:
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV
ในการทำเช่นนั้นคุณจะแปลง foo และ bar เป็นอักขระแต่ละตัวจากนั้นใช้การปฏิเสธของอักขระเหล่านั้นระหว่างพวกเขา:
$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/g; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV
ในด้านบน:
s/@/@A/g; s/{/@B/g; s/}/@C/gกำลังแปลง{และ}สตริงตัวยึดตำแหน่งที่ไม่สามารถมีอยู่ในอินพุตดังนั้นตัวอักษรเหล่านั้นจะพร้อมใช้งานสำหรับการแปลงfooและbarถึง
s/foo/{/g; s/bar/}/gกำลังแปลงfooและbarไปยัง{และ}ตามลำดับ
s/{[^{}]*}/<&>/gกำลังดำเนินการ op ที่เราต้องการ - แปลงfoo...barเป็น<foo...bar>
s/}/bar/g; s/{/foo/gคือการแปลง{และ}กลับไปและfoobar
s/@C/}/g; s/@B/{/g; s/@A/@/g กำลังแปลงสตริงตัวยึดตำแหน่งกลับไปเป็นอักขระดั้งเดิม
โปรดทราบว่าข้างต้นไม่พึ่งพาสายอักขระใด ๆ ที่ไม่มีอยู่ในอินพุตเนื่องจากสตริงดังกล่าวผลิตในขั้นตอนแรกและไม่สนใจว่า regexp ใด ๆ ที่คุณต้องการจับคู่เกิดขึ้นเนื่องจากคุณสามารถใช้งานได้{[^{}]*}บ่อยครั้งเท่าที่จำเป็น ในนิพจน์เพื่อแยกการจับคู่ที่แท้จริงที่คุณต้องการและ / หรือด้วยตัวดำเนินการจับคู่ตัวเลขเช่นเพื่อแทนที่เหตุการณ์ที่สองเท่านั้น:
$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/2; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC foo DEF bar GHI <foo KLM bar> NOP foo QRS bar TUV