นับจำนวนเส้นระหว่าง“ X” s


13

ฉันต้องการนับบรรทัดระหว่าง "X" นี่เป็นเพียงตัวอย่างเท่านั้น ฉันต้องใช้รหัสกับผลลัพธ์ทางชีวภาพที่ซับซ้อน ผมจะขอบคุณถ้าคุณสามารถแนะนำคำสั่งบางอย่างควรใช้awk, grepหรือsedเป็นผมคุ้นเคยกับบรรดา

ตัวอย่าง:

X
Y
Y
Y
X
Y
Y
Y
Y
X
Y
X

ผลลัพธ์ที่ต้องการ:

3
4
1

2
คุณอาจสนใจชีวสารสนเทศศาสตร์ถ้าคุณทำงานในสาขานี้
terdon

คำตอบ:


13

ด้วยawk:

$ awk '!/X/{count++}/X/{print count; count = 0}' input

3
4
1

เพิ่มจำนวนสำหรับทุกบรรทัดไม่ได้มีX; Xพิมพ์และการตั้งค่าการนับสำหรับสายที่มี


2
หากบรรทัดแรกไม่ใช่บรรทัดXจำนวนบรรทัดแรกจะยังคงถูกนับและแสดงผลด้วยโซลูชันนี้จนกว่าXจะจับคู่บรรทัดแรกด้วย EX (ไม่สามารถเพิ่มบรรทัดใหม่ในความคิดเห็น แต่พิจารณาว่ามีบรรทัดใหม่ระหว่างตัวละครแต่ละตัว P): Y X Y Y X Y Y Yจะส่งออก:1 2
Dan

1
@muru นี้จะไม่ทำงานหากไม่มี X ที่จุดสิ้นสุด (ต้องการเพิ่มEND{if (count)print count}) และสร้างบรรทัดว่างที่ X เริ่มต้นเพื่อหลีกเลี่ยงคุณสามารถเพิ่ม/X/&&countเงื่อนไขได้อีกด้วย
αғsнιη

1
หึ หนึ่งความคิดเห็นบ่นว่าผู้นำYไม่ควรนับเพราะพวกเขาไม่ได้อยู่ระหว่างสองXs; อีกคนหนึ่งบ่นว่าการต่อท้ายYจะไม่ถูกนับเพราะมันไม่ได้อยู่ระหว่างสองXวินาที ฉันจะรอให้ OP อธิบายหากจำเป็น ฉันสบายดีกับคำตอบนี้เหมือนเดิม
muru

12
$ awk '/X/ && prev{print NR-prev-1} /X/{prev=NR}' file
3
4
1

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

Awk อ่านไฟล์อินพุตแบบต่อบรรทัดโดยปริยาย

  • /X/ && prev{print NR-prev-1}

    สำหรับบรรทัดใด ๆ ที่มีXและหากเราได้กำหนดค่าไว้ก่อนหน้านี้ให้prevพิมพ์จำนวนบรรทัดปัจจุบันNRลบprevด้วยหนึ่ง

  • /X/{prev=NR}

    สำหรับสายการใด ๆ ที่มีXให้ตั้งค่าตัวแปรไปยังหมายเลขบรรทัดปัจจุบันprevNR


4
หืมดี การทารุณกรรมNRทำให้ฉันมีความคิด:awk '/X/{print NR - 1; NR = 0}' foo
muru

ขอบคุณมันให้ข้อมูลที่แน่นอนแก่ฉัน ซึ่งจำเป็น
Rhea

Muro: ดี & หากิน ยกเว้นการพิมพ์ค่าเดียวที่มากเกินไปมันใช้งานได้สำหรับฉันภายใต้ gawk และ mawk ฉันอยากรู้ว่าสิ่งนี้รับประกันพฤติกรรมหรือไม่ @EdMorton?
John1024

3
@ เชียเว้นเสียแต่ว่าบรรทัดแรกของคุณจะเป็นเสมอXมีความแตกต่างเล็กน้อยในผลลัพธ์ระหว่าง 2 คำตอบที่ฉันอธิบายในความคิดเห็นภายใต้คำตอบของ muru
ด่าน

1
@ John1024 ขอบคุณ! ฉันหวังว่ามันจะช่วยฉัน
Rhea

6

awkวิธีการง่ายๆอีกวิธีหนึ่งซึ่งทำงานกับข้อมูลตัวอย่างของ OP และหากXไม่ได้อยู่ในอันดับแรกหรือแม้แต่ใน X ที่ผ่านมาหรือซ้ำแล้วซ้ำอีก

awk -v RS='X' 'NF{print NF}' infile

เหนือขึ้นไปเป็นที่ถูกต้องเมื่อมีเพียงหนึ่งเขตข้อมูลในแต่ละบรรทัดที่มีค่าเริ่มต้น FS ใดช่องว่างมิฉะนั้นด้านล่างปรับในกรณีทั่วไปสำหรับการนับlinewise คุณสามารถป้อนข้อมูลของคุณรูปแบบในสถานที่ของXมี

awk -F'\n' -v RS='X' 'NF>2{print NF-2}'

ตัวอย่างอินพุต:

X
Y YYY Y
YY
YY Y YY YY Y Y
X
Y Y Y
X
Y
Y
X
X

ผลลัพธ์คือ:

3
1
2

1

คำตอบส่วนใหญ่ที่นี่ตรงกับเนื้อหาของบรรทัดที่จะนับโดยใช้นิพจน์ทั่วไปที่ฝังอยู่ในโปรแกรม Awk หากคุณต้องการจับคู่บรรทัดที่มีเนื้อหาที่อาจมีอักขระพิเศษ (กับ Awk หรือนิพจน์ทั่วไป) จะเป็นการดีกว่าถ้าจะเปรียบเทียบสตริงเพื่อความเท่าเทียมกัน ดังนั้นฉันจึงเสนอสคริปต์ Awk ต่อไปนี้เป็นคำตอบที่แตกต่างของmuru :

BEGIN {
    count = 0;
}

{
    if ($0 == needle) {
        if (count) {
            print count;
            count = 0;
        }
    } else {
        count++;
    }
}

เก็บไว้เป็นไฟล์ข้อความเช่นcount-rows.awkและเรียกใช้ดังนี้:

awk -f count-rows.awk -v needle=X input

คุณสามารถปรับค่าของneedleความชอบของคุณ ข้อดีของวิธีนี้คือคุณสามารถเรียกใช้โปรแกรมจากเชลล์สคริปต์ด้วยค่าที่กำหนดเองneedleโดยไม่มีปัญหาในการหลบหนี:

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