ฉันต้องการความช่วยเหลือเกี่ยวกับ Grep เพื่อเริ่มต้นในส่วน


8

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

green
blue
cyan
magenta
purple
brown
yellow
red
orange
more orange
more blue
this is enough

คำตอบ:


9

AWK Use AWK- ง่ายที่สุดเท่าที่จะทำได้:

awk '/yellow/,0' textfile.txt

วิ่งตัวอย่าง

$ awk '/yellow/,0' textfile.txt                                
yellow
red
orange
more orange
more blue
this is enough

grep

คุณสามารถใช้grepกับ--after-contextตัวเลือกเพื่อพิมพ์จำนวนบรรทัดหลังจากการแข่งขัน

grep 'yellow' --after-context=999999  textfile.txt

$(wc -l textfile.txt)สำหรับการตั้งค่าโดยอัตโนมัติจากบริบทคุณสามารถใช้ แนวคิดพื้นฐานคือถ้าคุณมีบรรทัดแรกเป็นคู่และคุณต้องการพิมพ์ทุกอย่างหลังจากการจับคู่นั้นคุณจะต้องรู้จำนวนบรรทัดในไฟล์ลบ 1 โชคดีที่--after-contextจะไม่ผิดพลาดเกี่ยวกับจำนวนของ เส้นดังนั้นคุณสามารถให้มันออกนอกช่วงได้อย่างสมบูรณ์ แต่ในกรณีที่คุณไม่ทราบจำนวนทั้งหมดจะทำ

$ grep 'yellow' --after-context=$(wc -l < textfile.txt) textfile.txt
yellow
red
orange
more orange
more blue
this is enough

หากคุณต้องการย่อคำสั่ง--after-contextเป็นตัวเลือกเดียวกับ-Aและ$(wc -l textfile.txt)จะขยายเป็นจำนวนบรรทัดตามด้วยชื่อไฟล์ ดังนั้นวิธีที่คุณพิมพ์textfile.txtเพียงครั้งเดียว

grep "yellow" -A $(wc -l textfile.txt)

หลาม

skolodya@ubuntu:$ ./printAfter.py textfile.txt                                 
yellow
red
orange
more orange
more blue
this is enough

DIR:/xieerqi
skolodya@ubuntu:$ cat ./printAfter.py                                          
#!/usr/bin/env python
import sys

printable=False
with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
           printable=True
        if printable:
           print line.rstrip('\n')

หรืออีกวิธีหนึ่งโดยไม่มีprintableธง

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
          for lines in f: # will print remaining lines
             print lines.rstrip('\n')
          exit()

คุณสามารถลดความซับซ้อนของคำสั่งgrep grep "yellow" -A $(wc -l textfile.txt)
ผู้บัญชาการ Byte

@ ByteCommander yup ก็สามารถทำได้เช่นกัน เพิ่งใช้ตัวเลือกเต็มรูปแบบเพื่อความชัดเจน
Sergiy Kolodyazhnyy

1
@ ByteCommander ช่างเป็นแฮ็คที่น่ารัก น่าเสียดายที่ใช้งานได้เนื่องจากไม่มีช่องว่างในชื่อไฟล์
kasperd

@kasperd โอ้ใช่คุณพูดถูก grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt"ในกรณีที่คุณจะต้องถอยกลับไปที่คำสั่งเดิมของ Serg
ผู้บัญชาการ Byte

5

คุณสามารถทำได้โดย:

awk '/yellow/{f=1}f' file

โดยที่ "file" เป็นชื่อไฟล์ที่มีข้อความของคุณ


จิตใจที่ยิ่งใหญ่คิดเหมือนกัน> :)
Sergiy Kolodyazhnyy

5

ไม่ได้grepแต่ใช้sed:

sed -n '/^yellow$/,$p' file
  • -n: ยับยั้งการพิมพ์
  • /^yellow$/,$: ช่วงที่อยู่ที่เริ่มต้นจากการจับคู่บรรทัดแรกกับyellowการรวมบรรทัดสุดท้าย
  • p: พิมพ์บรรทัดในช่วงที่อยู่
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough

5

ไปงานเลี้ยงสาย :)

การใช้grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P ช่วยให้เราสามารถใช้ Regex ที่รองรับ Perl ได้

  • -z ทำให้อินพุตไฟล์คั่นด้วย ASCII NUL แทนที่จะขึ้นบรรทัดใหม่

  • -o ใช้เวลาเพียงส่วนที่ต้องการ

  • (?s)เป็นตัวดัดแปลง DOTALL ทำให้เราสามารถจับคู่บรรทัดใหม่โดยใช้โทเค็น.(ตัวอักษรใด ๆ )

  • ใน\n\K, \nตรงกับขึ้นบรรทัดใหม่, \Kทิ้งการแข่งขัน

  • yellow\n.*ตรงyellowตามด้วยการขึ้นบรรทัดใหม่และทุกอย่างหลังจากนี้จะถูกเลือกด้วยและแสดงในผลลัพธ์

ตัวอย่าง:

% grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
yellow
red
orange
more orange
more blue
this is enough

ใช้น้อยpython:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines คือรายการที่มีบรรทัดทั้งหมดของไฟล์ (พร้อมการขึ้นบรรทัดใหม่ด้วย)

  • lines.index('yellow\n')ให้ดัชนีต่ำที่สุดlinesที่yellow\nเราพบ

  • lines[lines.index('yellow\n'):]จะใช้การแบ่งส่วนรายการเพื่อให้ได้ส่วนเริ่มต้นyellow\nจนถึงสิ้นสุด

  • join จะเข้าร่วมองค์ประกอบของรายการเพื่อส่งออกเป็นสตริง


ดีมาก แต่คุณควรพูดถึงว่ารหัส Python ค้นหาทั้งบรรทัดที่เท่ากับ "สีเหลือง" เท่านั้นมันไม่ได้ตรวจจับเช่นบรรทัดเช่น "มากกว่าสีเหลือง"
ผู้บัญชาการ Byte

@ByteCommander จากตัวอย่างของ OP ฉันคิดว่ามันชัดเจนว่าพวกเขาต้องการจับคู่yellowในบรรทัด .. ถ้ายังไม่เป็นเช่นนั้นเราจำเป็นต้องเปลี่ยนpythonalgo ของตัวเอง ..
heemayl

ใช่แน่นอน. นั่นไม่ได้เป็นการวิจารณ์ แต่เป็นเพียงคำแนะนำในการปรับปรุงคำตอบ คนอื่นที่อ่านข้อความนี้อาจคิดว่ารหัสทำงานได้เหมือนกันgrepและไม่ตรงกับบรรทัดเต็มเท่านั้น ฉันยกระดับ btw
ผู้บัญชาการ Byte

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