คำสั่ง unix เพื่อตรวจสอบช่วงของคำในข้อความ


3

คำสั่ง unix ใดที่ฉันสามารถใช้เพื่อกำหนดระยะห่างบรรทัดที่คำปรากฏในข้อความ "span" เท่ากับจำนวนบรรทัดของอินสแตนซ์สุดท้ายของคำลบด้วยหมายเลขบรรทัดของอินสแตนซ์แรกของคำ

1| unix is on two lines
2| once above, and once below
3| unix

ในตัวอย่างข้างต้น "span" ของ 'unix' จะเป็น 2 (3-1)

จนถึงตอนนี้ฉันพยายามใช้ grep -n แต่ฉันไม่คิดว่า grep มีพลังมากพอ บางทีการใช้งาน sed หรือ awk บ้าง?

ขอบคุณ!


1
แม้ว่าฉันจะตอบแล้ว span จะเป็น 2 เพราะมีสองบรรทัดที่คำ unix ปรากฏขึ้นหรือเพราะคำ unix apears สองครั้งในบรรทัดเดียวกัน
fmanco

Span = (บรรทัดสุดท้ายที่มี 'unix' - บรรทัดแรกที่มี 'unix') ดังนั้นเนื่องจาก 'unix' ปรากฏในบรรทัด 1,2,3 (หรือ 0,1,2 หากคุณต้องการ) 3-1 เท่ากับ 2 (หรืออีกครั้ง 2 -0 = 2) ดังนั้น "span" คือ 2 ขออภัยที่ไม่ชัดเจน
Ocasta Eshu

โพสต์แก้ไขเพื่อความชัดเจน
Ocasta Eshu

คำตอบ:


4

การใช้ awk

คำสั่ง

awk '{ if($0 ~ /PATTERN/) { if(!FIRST) FIRST=NR; LAST=NR } } END { print LAST-FIRST }' FILE

มันทำงานอย่างไร

  • awk '{ COMMANDS } END { FINALCOMMAND }' FILE รัน COMMMANDS สำหรับทุกบรรทัดของ FILE.

    หลังจากนั้นมันรัน FINALCOMMAND.

  • if($0 ~ /PATTERN/) { ... } ตรวจสอบว่า PATTERN เกิดขึ้นในสาย ( $0 )

    ถ้าเป็นเช่นนั้น ... ถูกประหารชีวิต

  • The first time the pattern occurs, FIRST` จะว่างเปล่า

    ดังนั้น, if(!FIRST) FIRST=NR จะเก็บหมายเลขบรรทัด ( NR ) ใน FIRST.

  • สำหรับทุกเหตุการณ์ LAST=NR จะเก็บหมายเลขบรรทัด ( NR ) ใน LAST.

    หลังจากประมวลผลเหตุการณ์ทั้งหมดแล้ว LAST จะถือหมายเลขบรรทัดของการเกิดขึ้นครั้งสุดท้าย

  • print LAST-FIRST พิมพ์ความแตกต่างระหว่างหมายเลขบรรทัดสุดท้ายและบรรทัดแรก


ใช้เท่านั้น grep, head และ tail

ต้นฉบับ

MATCHES=$(grep -n PATTERN FILE)
FIRST=$(echo "$MATCHES" | head -n 1 | grep -Po "^\d+"); [ $FIRST ] || FIRST=0
LAST=$(echo "$MATCHES" | tail -n 1 | grep -Po "^\d+"); [ $LAST ] || LAST=0
SPAN=$(($LAST - $FIRST))

มันทำงานอย่างไร

  • grep -n PATTERN FILE แสดงทุกบรรทัดใน FILE การจับคู่ PATTERNนำหน้าด้วยหมายเลขบรรทัด

  • echo "$MATCHES" | head -n 1 แสดงให้เห็นว่า เป็นครั้งแรก สายของ MATCHESและ grep -Po "^ *\d+" กรองทุกอย่างยกเว้นหมายเลขบรรทัด

    ภายหลัง [ $FIRST ] || FIRST=0 ตรวจสอบว่า FIRST ได้รับการกำหนด หากยังไม่ได้ตั้งค่าเป็น 0.

  • echo "$MATCHES" | tail -n 1 แสดงให้เห็นว่า สุดท้าย สายของ MATCHESและ grep -Po "^ *\d+" กรองทุกอย่างยกเว้นหมายเลขบรรทัด

    ภายหลัง [ $LAST ] || LAST=0 ตรวจสอบว่า LAST ได้รับการกำหนด หากยังไม่ได้ตั้งค่าเป็น 0.

  • $(($LAST - $FIRST)) คำนวณความแตกต่างระหว่างหมายเลขบรรทัดสุดท้ายและบรรทัดแรก


0

นี้จะหาช่วงระหว่าง เป็นครั้งแรก และ สุดท้าย การเกิดขึ้นของคำ (เช่นไม่ได้รับการพิจารณาคำกลาง) ...

หมายเหตุ: sed คำสั่ง i และ a (insert and ผนวก) จะต้องเป็นคำสั่งสุดท้ายในบรรทัด

eval "$(sed -ne "1 i b=
                 /\<$word\>/{=; i ;e=
                 =}
                 $ {a ;echo \$((e-b))
                 }
                " "$file" | tr -d '\n')"

หรืออันนี้ซึ่งท่อ sed ไปยัง sed แต่อาจจะง่ายกว่า

eval "$(sed -n "/\<$word\>/=" "$file" |
        sed -n '1{i b=
             p};${i;e=
             p;   a;echo \$((e-b))
              }' | tr -d '\n')"   

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