"X" s के बीच की रेखाएँ गिनें


13

मैं "X" के बीच की पंक्तियों को गिनना चाहता हूं। यह सिर्फ एक उदाहरण है; मुझे एक जटिल जैविक परिणाम के लिए कोड लागू करना होगा। मैं आभारी रहूंगा यदि आप कुछ कमांड का सुझाव दे सकते हैं, अधिमानतः उपयोग कर रहे हैं awk, grepया sedजैसा कि मैं उन लोगों से परिचित हूं।

उदाहरण:

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

वांछित आउटपुट:

3
4
1

2
यदि आप इस क्षेत्र में काम कर रहे हैं, तो आपको जैव सूचना विज्ञान में रुचि हो सकती है ।
टेराडन

जवाबों:


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
@ एमआरयू यह काम नहीं करेगा यदि कोई एक्स (अंत में END{if (count)print count}) की आवश्यकता नहीं थी , और खाली लाइन का उत्पादन जहां एक्स शुरू करने से बचने के लिए था, तो आप /X/&&countशर्त में भी जोड़ सकते हैं
αғsнιη

1
हे। एक टिप्पणी की शिकायत है कि अग्रणी Yएस को नहीं गिना जाना चाहिए क्योंकि वे दो Xएस के बीच बिल्कुल नहीं हैं ; दूसरे की शिकायत है कि अनुगामी की Yगणना नहीं की गई है क्योंकि वे दो सों के बीच नहीं हैं X। मैं ओपी के स्पष्ट होने की प्रतीक्षा करूँगा, यदि आवश्यक हो; मैं इस जवाब के साथ ठीक हूं क्योंकि यह तब तक है।
मुरु

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

यह काम किस प्रकार करता है:

Awk implicitly इनपुट फ़ाइलों के माध्यम से लाइन द्वारा पढ़ता है।

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

    किसी भी पंक्ति के लिए जिसमें सम्‍मिलित है Xऔर यदि हमने पहले एक मान दिया है prev, तो वर्तमान लाइन की संख्या NR, माइनस prevमाइनस एक का प्रिंट आउट लें ।

  • /X/{prev=NR}

    किसी भी लाइन के लिए जिसमें Xचर prevहै, वर्तमान लाइन नंबर पर सेट करें NR


4
हुह, अच्छा है। गाली NRदेने से मुझे एक विचार मिलता है:awk '/X/{print NR - 1; NR = 0}' foo
muru

धन्यवाद, यह मुझे सटीक जानकारी देता है। जिसकी आवश्यकता है।
रिया

Muro: अच्छा और मुश्किल। एक मूल्य को बहुत अधिक छापने के अलावा, यह मेरे लिए gawk और mawk के तहत काम करता है। मैं इसके लिए उत्सुक हूं कि क्या यह व्यवहार की गारंटी है। @EdMorton?
जॉन 1024

3
@ जब तक आपकी पहली पंक्ति हमेशा एक नहीं होती X, तब तक 2 जवाबों के बीच आउटपुट में एक छोटा सा अंतर होता है जैसा कि मैंने muru के उत्तर के तहत एक टिप्पणी में समझाया था।
डेन

1
@ जॉन 1024 थैंक्यू! मुझे उम्मीद है कि यह मेरी मदद करेगा।
रिया

6

एक और सरल awkदृष्टिकोण जो ओपी के सैंपल डेटा पर काम करता है और यदि Xपहले या अंतिम या बार-बार एक्सएस में भी नहीं था

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

जब वहाँ डिफ़ॉल्ट के साथ प्रत्येक पंक्ति में केवल एक ही क्षेत्र किसी भी FS है ऊपर सही है व्हाइटस्पेस , नीचे अन्यथा उनकी गिनती के लिए सामान्य स्थिति में संशोधित किया गया है linewise । आप अपने PATTERN को 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 या नियमित अभिव्यक्ति के लिए) तो वास्तव में समानता के लिए तार की तुलना करना बेहतर होगा। इसलिए मैं निम्नलिखित अर्क स्क्रिप्ट को मौरू के उत्तर के एक संस्करण के रूप में प्रस्तावित करता हूं :

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.