พิมพ์เอาต์พุตเฉพาะหลังจากค้นหารูปแบบ


13

มีสคริปต์ (เรียกว่าechoer) ที่พิมพ์หน้าจอเพื่อรวบรวมข้อมูลจำนวนมาก ฉันต้องการเห็นลายเส้นหลังจากพบลวดลาย

ฉันนึกภาพการใช้โซลูชันเพื่อให้ดูเหมือน

echoer | solution_command <pattern>

เป็นการดีที่patternจะเป็นการแสดงออกปกติ แต่สตริงค่ายากจะเพียงพอสำหรับฉัน


รูปแบบสามารถเป็นหลายสายได้หรือไม่
Inian

A glob? คุณหมายถึงการแสดงออกปกติหรือไม่ Globs เหมาะสมกว่าสำหรับการขยายชื่อไฟล์
terdon

@Inian ฉันไม่แน่ใจว่าฉันเข้าใจคำถาม คุณหมายถึงถามว่าฉันต้องการให้สิ่งนี้ทำงานร่วมกับการแบ่งแยกหรือไม่?
user23146

คำตอบ:


21

AWK สามารถทำได้ด้วยช่วงของรูปแบบซึ่งอนุญาตให้ใช้นิพจน์ทั่วไปใด ๆ :

echoer | awk '/pattern/,0'

จะพิมพ์echoer's patternการส่งออกที่เริ่มต้นด้วยการจับคู่บรรทัดแรก

AWK ขึ้นอยู่กับรูปแบบและโดยทั่วไปจะใช้กับวิธีการ“ ถ้ารูปแบบนี้ตรงกัน “ รูปแบบนี้” อาจเป็นช่วงของรูปแบบที่กำหนดเป็น“ เมื่อรูปแบบนี้ตรงกันเริ่มต้นทำสิ่งนี้จนกระทั่งรูปแบบอื่น ๆ นี้ตรงกับ”; นี่คือการระบุโดยการเขียนสองรูปแบบคั่นด้วยเครื่องหมายจุลภาคดังกล่าวข้างต้น รูปแบบสามารถจับคู่ข้อความได้เช่นเดียวกับ/pattern/ที่ซึ่งบรรทัดปัจจุบันถูกตรวจสอบกับรูปแบบตีความเป็นนิพจน์ทั่วไป พวกเขายังสามารถเป็นนิพจน์ทั่วไปได้รับการประเมินสำหรับทุกบรรทัดและพิจารณาว่าตรงกันหรือไม่หากผลลัพธ์ไม่เป็นศูนย์หรือไม่ว่างเปล่า

ใน AWK การกระทำเริ่มต้นคือการพิมพ์บรรทัดปัจจุบัน

การรวมทั้งหมดเข้าด้วยกันawk '/pattern/,0'จะมองหาการจับคู่บรรทัดpatternและเมื่อพบแล้วให้ใช้การดำเนินการเริ่มต้นกับทุกบรรทัดจนกว่า0เงื่อนไขตรงกัน (ไม่ใช่ศูนย์) awk '/pattern/,""'ก็จะทำงานเช่นกัน

คู่มือการเพ่งพิศไปในรายละเอียดมากขึ้น


3
ฉันไม่ได้ตระหนักถึงความหมายของช่วงที่มีศูนย์เป็นจุดสิ้นสุดของช่วง ขอบคุณ!
Kusalananda

@StephenKitt นี่มันเยี่ยมมาก! เกิดอะไรขึ้นถ้าผมอยากจะพิมพ์จนกว่าจะจับคู่0? มันจะเป็น/pattern/,/0/อย่างไร คำตอบที่ดูเหมือนจะเขียนการกระทำเริ่มต้นอย่างชัดเจนคืออะไร?
user23146

@ user23146 ใช่/pattern/,/0/จะพิมพ์จนกว่าจะพบบรรทัด (บันทึก) ที่มี“ 0” เขียนข้อมูลโค้ดในคำตอบที่มีการดำเนินการอย่างชัดเจนให้หรือเท่ากัน/pattern/,0 { print $0 } /pattern/,0 { print }
สตีเฟ่น Kitt

7

ภาระsedผูกพันที่เทียบเท่ากับหนึ่งใน @ StephenKitt awk:

sed '/pattern/,$!d'

patternมีการตีความว่าเป็นนิพจน์ทั่วไปพื้นฐานเหมือนในgrep(ตรงข้ามกับนิพจน์ทั่วไปเพิ่มเติมในawk/ egrep/ grep -E) sedการใช้งานบางอย่างมีตัวเลือก-E(BSD, ast, GNU / busybox, POSIX เร็ว ๆ นี้) หรือ-r(GNU, ssed, busybox, BSD ล่าสุดบางตัวเลือก) เพื่อให้ขยายนิพจน์ปกติแทนและบางส่วนมี-P(ast) หรือ-R(ssed) เพื่อให้ การแสดงออกปกติ Perl เหมือน

ด้วยperl:

perl -ne 'print if /pattern/ .. undef'

4

ด้วย GNU และ grep * BSD:

grep -A1000000000 pattern file

ถ้าไฟล์ของคุณมีมากกว่า 1M บรรทัดนั่นแหล่ะ


0

หากคุณใช้เพจเจอร์เช่นlessเพื่อดูผลลัพธ์จากคำสั่ง

less +pattern

0

awk สำหรับบรรทัดหลังจาก (แต่ไม่รวม) รูปแบบแรกที่ตรงกัน

หากบรรทัดที่มีรูปแบบทริกเกอร์เทียบเท่ากับ "CUT HERE" คุณสามารถตัดออกจากเอาต์พุตที่พิมพ์ได้:

echoer | awk 'flag ; /pattern/ { flag=1 }'

แต่ละบรรทัดของการป้อนข้อมูลจะทำงานผ่านสององค์ประกอบในรหัส awk องค์ประกอบแรกคือflagซึ่ง awk ตีความว่า "พิมพ์บรรทัดหากตัวแปรที่flagไม่ใช่ศูนย์" เนื่องจากตัวแปร awk เป็น 0 โดยค่าเริ่มต้นสิ่งนี้จะไม่พิมพ์อะไรเลย

คอมโพเนนต์ที่สอง/pattern/ { flag=1 }ตั้งค่าแฟล็กเป็น 1 ทันทีที่ตรวจพบรูปแบบและแฟล็กจะเก็บค่านั้นไว้สำหรับการรันที่เหลือ

เมื่อถึงเวลาที่ตรวจพบรูปแบบครั้งแรกโอกาสที่จะพิมพ์บรรทัดอินพุตนั้นได้ผ่านไปแล้ว บรรทัดถัดมาใด ๆ (รวมถึงบรรทัดเพิ่มเติมที่มีลวดลาย) จะพิมพ์ออกมา


0

ทุบตี

ค่อนข้างจะกล้าหาญ แต่ก็ใช้งานได้

#!/bin/bash
found=false
while IFS= read -r; do
    if $found || [[ $REPLY =~ pattern ]]; then
        found=true
        printf '%s\n' "$REPLY"
    fi
done

รุ่นนี้อาศัยcatแต่ง่ายต่อการเข้าใจ

#!/bin/bash
while IFS= read -r; do
    if [[ $REPLY =~ pattern ]]; then
        printf '%s\n' "$REPLY"
        break
    fi
done
cat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.