วิธีการแสดงเส้นหลังจากการจับคู่ grep แต่ละครั้งจนถึงการจับคู่ที่เฉพาะเจาะจงอื่น ๆ


44

ฉันรู้ว่าด้วยการใช้"-A NUM"สวิตช์ฉันสามารถพิมพ์จำนวนบรรทัดต่อท้ายเฉพาะหลังจากการแข่งขันแต่ละครั้ง ฉันแค่สงสัยว่ามันเป็นไปได้ที่จะพิมพ์เส้นต่อท้ายจนกว่าจะพบคำที่เฉพาะเจาะจงหลังจากการแข่งขันแต่ละครั้ง เช่นเมื่อฉันค้นหา "Word A" ฉันต้องการดูบรรทัดที่มีคำว่า "Word A" และบรรทัดหลังจากนั้นจนถึงบรรทัดที่มี "Word D"

บริบท:

Word A
Word B
Word C
Word D
Word E
Word F

คำสั่ง:

grep -A10 'Word A'

ฉันต้องการผลลัพธ์นี้:

Word A
Word B
Word C
Word D

คำตอบ:


73

ดูเหมือนว่าคุณต้องการพิมพ์บรรทัดระหว่าง ' Word A' และ ' Word D' (รวม) ผมขอแนะนำให้คุณใช้แทนsed grepมันช่วยให้คุณสามารถแก้ไขช่วงของการป้อนข้อมูลซึ่งเริ่มต้นและสิ้นสุดด้วยรูปแบบที่คุณต้องการ คุณควรบอกsedให้พิมพ์ทุกบรรทัดในช่วงและไม่มีบรรทัดอื่น:

sed -n -e '/Word A/,/Word D/ p' file

เคล็ดลับใด ๆ เกี่ยวกับวิธีทำให้เป็นเอกสิทธิ์ (สำหรับสถานการณ์ทั่วไปไม่ใช่เฉพาะ OP)
2rs2ts

4
@ 2rs2ts เพื่อให้เป็นเอกสิทธิ์เพียงแค่เพิ่ม | sed -e '1d;$d'นั่นคือเอาบรรทัดแรกและบรรทัดสุดท้าย
holroy

และถ้าคุณต้องการยกเว้นทุกบรรทัดระหว่าง - นั่นคือคุณต้องการเห็นเส้นที่อยู่นอกคู่ที่ตรงกัน - จากนั้น: sed -n -e '/pattern A/,/pattern D/d; p'สิ่งนี้บอกว่า "ลบจากรูปแบบ A ถึงรูปแบบ D และพิมพ์ทุกอย่าง" น่าเสียดายที่การแข่งขันครั้งนี้โลภมาก นั่นหมายความว่าถ้ารูปแบบ A และ D ปรากฏมากกว่าหนึ่งครั้งคุณจะต้องจับคู่จากรูปแบบแรก A กับรูปแบบสุดท้าย D ฉันกลัว Perl หรือ Python เป็นเพื่อนของคุณถ้าเป็นเช่นนั้น
fbicknel

16

ทำไมไม่ใช้ awk?

awk '/Word A/,/Word D/' filename

2
sed ดูเหมือนจะสามารถทำสิ่งนี้ได้อย่างมีประสิทธิภาพมากขึ้นถ้ามีไฟล์จำนวนมากเข้ามาเกี่ยวข้อง awk อาจจะง่ายกว่าที่จะจำได้ แต่ sed ดูเหมือนจะคุ้มค่ากับโน้ตที่ติดหนึบในสมองของฉัน
JimNim

1
awk จะดีกว่าหากWord DตรงกับบรรทัดเดียวกันWord Aและอาจเป็นที่อื่นเช่นWord A Word D\nWord Dกับ sed จะแสดงสองบรรทัดโดยที่ awk จะแสดงหนึ่งบรรทัด นอกจากนี้เรายังสามารถใช้ตัวแปรที่มี awk เช่นawk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file"sed อาจมีประสิทธิภาพมากขึ้น แต่เมื่อจัดการกับการค้นหาสองสายที่อาจหรือไม่ - อาจตกอยู่ในบรรทัดเดียวกัน awk มีความน่าเชื่อถือมากขึ้น
S0AndS0

ดูเหมือนว่า awk ที่ดีกว่าที่จะจัดการกับกรณีที่ไฟล์มีลำดับของAและBและคุณเพียงต้องการที่จะจับสิ่งที่อยู่ระหว่างลำดับเช่นแต่ละ ดูเหมือนว่า sed จะไม่ปฏิบัติตามความหมายเหล่านี้ในกรณีของฉันอย่างน้อย
Matan

9
perl -lne 'print if /Word A/ .. /Word D/' file

หรือ

cat file | perl -lne 'print if /Word A/ .. /Word D/'

1
+1 เพื่อตอบโต้การโหวตลงโดยไดรฟ์ ฉันจะยังคงใช้sedสิ่งนี้อยู่เว้นเสียแต่ว่าคุณต้องการพลังของการแสดงออกปกติของ Perl เพื่อเลือกเส้นแบ่งเขต
tripleee

คนที่เขียนบทกวีในยุค 70 ต้องขอบคุณ :-)
Matan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.