मैचिंग लाइन से मैचिंग लाइन और nth लाइन प्रिंट करें


18

मैं मिलान की गई रेखा और 4 वीं पंक्ति को मिलान वाली रेखा से प्रिंट करने की कोशिश कर रहा हूं (वह रेखा जिसमें वह अभिव्यक्ति है जिसे मैं खोज रहा हूं)।

मैं निम्नलिखित कोड का उपयोग कर रहा हूं: sed -n 's/^[ \t]*//; /img class=\"devil_icon/,4p' input.txt

लेकिन यह केवल मिलान वाली रेखा को प्रिंट करता है।

यह केवल 4 वीं पंक्ति प्रिंट करता है। awk 'c&&!--c;/img class=\"devil_icon/{c=4}' input.txt

मुझे मैचेड लाइन और 4th लाइन दोनों को ही प्रिंट करना होगा।


उपयोग egrep "pattern" -A4
वैलेंटाइन बजरमी

@ val0x00ff जो लाइनों को बीच में भी प्रिंट करता है .. वह यह है: यह मिलान वाली लाइन से शुरू होने वाली अगली 4 लाइनों को प्रिंट करता है
debal

आप कह रहे हैं "मैं मिलान की गई रेखा और मिलान की गई रेखा से 4 वीं पंक्ति को प्रिंट करने का प्रयास कर रहा हूं"। यह grep -A 4 "pattern" file | sed -n '4p'वही करता है जो आप चाहते हैं, जब तक कि मैं आपको गलत नहीं समझ रहा हूं
वैलेंटाइन बजरमी

नहीं, यह नहीं है। उपरोक्त कोड का आउटपुट था </td>जो
बजे

जवाबों:


18

Awk में, आप इसे निम्नानुसार करेंगे

awk '/pattern/{nr[NR]; nr[NR+4]}; NR in nr' file > new_file`

या

awk '/pattern/{print; nr[NR+4]; next}; NR in nr' file > new_file`

व्याख्या

पहला समाधान सभी रेखाओं को मिलाता है जो मेल खाती हैं pattern। जब यह एक मैच पाता है तो यह NRसरणी में रिकॉर्ड संख्या ( ) को संग्रहीत करता है nr। यह NRएक ही एरे से चौथे रिकॉर्ड को भी संग्रहीत करता है । यह द्वारा किया जाता है nr[NR+4]। प्रत्येक रिकॉर्ड ( NR) को यह देखने के लिए चेक किया जाता है कि क्या यह nrसरणी में मौजूद है , यदि ऐसा रिकॉर्ड मुद्रित है।

दूसरा समाधान अनिवार्य रूप से उसी तरह से काम करता है, सिवाय इसके कि जब उसका सामना होता है तो यह patternउस रेखा को प्रिंट करता है, और फिर 4 वें रिकॉर्ड को सरणी में आगे रखता है nr, फिर अगले रिकॉर्ड पर जाता है। फिर जब awkइस चौथे रिकॉर्ड का सामना NR in nrहोगा तो ब्लॉक निष्पादित हो जाएगा और इस +4 रिकॉर्ड को उसके बाद प्रिंट करेगा।

उदाहरण

यहाँ एक उदाहरण डेटा फ़ाइल, है sample.txt

$ cat sample.txt 
1
2
3
4 blah
5
6
7
8
9
10 blah
11
12
13
14
15
16

1 समाधान का उपयोग करना:

$ awk '/blah/{nr[NR]; nr[NR+4]}; NR in nr' sample.txt 
4 blah
8
10 blah
14

दूसरा समाधान का उपयोग करना:

$ awk '/blah/{print; nr[NR+4]; next}; NR in nr' sample.txt 
4 blah
8
10 blah
14

3
अच्छा लगा, १। आप awkयहां बहुत सारे शार्टकट का उपयोग कर रहे हैं, क्या आप एक संक्षिप्त विवरण जोड़ सकते हैं (प्रिंट की तरह चीजें जो awk में निहित हैं और जो सरणियाँ सहयोगी हैं आदि)?
terdon

@terdon से सहमत कृपया आप कोड को थोड़ा समझा सकते हैं।
डीबेल

@ एसएलएम में सुधार और पूरा जवाब देने के लिए धन्यवाद!
वैलेंटाइन बजरमी

1
उत्तर के लिए धन्यवाद, मैंने इसके साथ कुछ नया भी सीखा।
स्लम

4
sed -n 's/^[ \t]*/; /img class=\"devil_icon/,+4 { 3,5d ; p }' input.txt

मैं केवल मुद्रण से पहले उपयुक्त लाइनों का विलोपन जोड़ रहा हूँ { 3,5d ; p }


आपकी अभिव्यक्ति एक त्रुटि उत्पन्न करती है: sed: -e expression #1, char 18: unknown option to s'`
खनिज

4

आप के -Aसाथ विकल्प का प्रयास कर सकते हैं grep, जो निर्दिष्ट करता है कि मिलान रेखा के बाद कितनी लाइनें मुद्रित की जानी चाहिए। इसके साथ युगल sed, और आपको आवश्यक लाइनें मिलेंगी।

grep -A 4 pattern input.txt | sed -e '2,4d'

का उपयोग करते हुए sed, हम दूसरी पंक्ति से चौथी तक हटाते हैं।


3
यह patternफ़ाइल का एकल मिलान मानता है ।
terdon

2

यहाँ पर्ल में एक तरीका है जो मेल खाती लाइनों की एक मनमानी संख्या से निपट सकता है:

perl -ne '/pattern/ && do{$c=$.; print}; $.==$c+4 && print' file > new_file`

पर्ल में। विशेष चर $.वर्तमान लाइन संख्या है। इसलिए, हर बार जब मैं एक लाइन मिलान करता patternहूं, तो मैं इसे प्रिंट करता हूं और इसके लाइन नंबर को सहेजता हूं $c। मैं तब फिर से प्रिंट करता हूं जब वर्तमान लाइन संख्या पहले से मुद्रित एक से 4 अधिक है।


0
awk 'c&&!--c;/img class=\"devil_icon/{c=4};/img class=\"devil_icon/' input.txt

आप अनिवार्य रूप से एक खोज और प्रतिस्थापित कर रहे हैं। आप एक ही कमांड में एक खोज जोड़ सकते हैं और यह उन दोनों को प्रिंट करेगा :)

awk 'c&&!--c;/pattern/{c=4};/pattern/' input.txt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.