मैच से पहले और बाद में Nth और Mth लाइनों को वापस करने के लिए grep


12

मुझे पता है कि grep के साथ मैं खेतों का उपयोग कर सकता हूं -Aऔर -Bएक मैच से पिछली और अगली पंक्तियों को खींच सकता हूं ।

हालाँकि वे मैच के बीच की सभी लाइनों को खींचते हैं, हालांकि कई लाइनें निर्दिष्ट हैं।

grep -r -i -B 5 -A 5 "match" 

मैं एक मैच से पहले केवल 5 वीं पंक्ति और मैच लाइन के अलावा मैच के बाद 5 वीं पंक्ति प्राप्त करना चाहता हूं और बीच की लाइनें नहीं मिलती।

क्या ऐसा करने का कोई तरीका है grep?


1
आप इसे सेड में लगाकर कर सकते हैं। मैंने अभी इसका परीक्षण किया और इसने काम किया, लेकिन यह केवल तब काम किया जब फ़ाइल में 1 सटीक मिलान था: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
टेरेंस

@ सुझाव के लिए धन्यवाद, जैसा कि आप उल्लेख करते हैं, क्योंकि मैं 1000 लाइनों को इकट्ठा कर रहा हूं यह काम नहीं करेगा।
चोलिडा

मुझे नहीं लगता कि grep अपने आप से काम करेगा ... मैं आपके लिए एक बैश स्क्रिप्ट पर काम कर रहा हूं
जोशुआ बेस्नेट

कोई दिक्कत नहीं है! यह देखने में रुचि है कि आपको क्या उत्तर मिलेगा। =)
टेरेंस

यह एक फ़ाइल में या कई फ़ाइलों में है?
जोशुआ बेसनीटेट

जवाबों:


1

जिस टूल का आप उपयोग करना चाहते हैं, उसे sift कहा जाता है। यह मूल रूप से स्टेरॉयड पर एक grep है। समानांतर में ग्रीप। Sift के पास विकल्पों की एक बड़ी मात्रा है जो आप वास्तव में करना चाहते हैं - विशेष रूप से एक मैच (s) के सापेक्ष एक विशेष पंक्ति को वापस करने के लिए जो कुछ पाठ द्वारा / पूर्ववर्ती हो सकती है।

यह मुझे आश्चर्यचकित करता है कि झारखंड मुख्यधारा का गन्नू नहीं है क्योंकि इसे गो भाषा में लिखा गया था, लेकिन लिनक्स पर यह ठीक-ठाक है। आईटी सभी समानांश भारी मात्रा में पाठ का उपयोग करके समानांतर में खोज करता है जहां grep को ऐसा करने में केवल सप्ताह लगते हैं।

Sift वेबसाइट - उदाहरण देखें


AskUbuntu में आपका स्वागत है, उत्तर देने के लिए धन्यवाद। आपको एक सीएलआई उदाहरण प्रदान करने की आवश्यकता है जो इस विशिष्ट समस्या को हल करने के लिए वेबसाइट को लिंक प्रदान करने के बजाय हल कर सके। यह एक प्रश्नोत्तर है, धन्यवाद।
बर्नार्ड वेई

12

अगर:

cat file
a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o

फिर:

awk '
    {line[NR] = $0} 
    /match/ {matched[NR]} 
    END {
        for (nr in matched)
            for (n=nr-5; n<=nr+5; n+=5) 
                print line[n]
    }
' file
a
f match
k
d
i match
n

+1, लेकिन क्या आप शब्दार्थ की व्याख्या कर सकते हैं /match/ {matched[NR]}? मैंने कभी भी एक सरणी या चर को पूरे कमांड के रूप में नहीं देखा है। क्या यह प्रत्येक मिलान रेखा के वर्तमान रिकॉर्ड संख्या को सरणी में डाल रहा है।
जो

यह एक अजीब विषमता है: यदि आप असाइनमेंट के बिना एक एरे तत्व को संदर्भित करते हैं, तो उस एरी को ऐरे में जोड़ा जाता है (वैल्यू के बिना)। तब वह कुंजी अभिव्यक्ति में दिखाई देती है key in array। मैं जो कर रहा हूं वह उन रेखाओं को याद कर रहा है जहां पैटर्न दिखाई देता है
ग्लेन जैकमैन

6

यह मूल रूप से ग्लेन का समाधान है, लेकिन बैश, ग्रेप और सेड के साथ लागू किया गया है।

grep -n match file |
    while IFS=: read nr _; do
        sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
    done

ध्यान दें कि 1 से कम लाइन नंबर, sed त्रुटि करेगा, और फ़ाइल में लाइनों की संख्या से अधिक लाइन नंबर इसे कुछ भी नहीं प्रिंट करेगा।

यह सिर्फ नंगे न्यूनतम है। इसे पुनरावर्ती बनाने के लिए और उपरोक्त पंक्ति संख्या के मामलों को संभालने में कुछ करना होगा।


6

यह केवल के साथ नहीं किया जा सकता है grep। यदि edएक विकल्प है:

ed -s file << 'EOF' 
g/match/-5p\
+5p\
+5p
EOF  

स्क्रिप्ट मूल रूप से कहती है: / मैच / के हर मैच के लिए, उससे पहले 5 लाइनों को प्रिंट करें, उसके बाद 5 लाइनों को, उसके बाद 5 लाइनों को।


5
@ubashu क्या आपको लगता है कि यह एक साधारण फ्लैट देने वाले ओपी के लिए अधिक सहायक होगा "यह जीआरईपी के साथ नहीं किया जा सकता है"? मैं ओपी की समस्या को हल करने के लिए एक अच्छा विकल्प होने के बारे में विश्वास करता हूं। सहायता केंद्र से: "क्या, विशेष रूप से, सवाल पूछ रहा है? सुनिश्चित करें कि आपका उत्तर प्रदान करता है - या व्यवहार्य विकल्प। उत्तर 'ऐसा नहीं' किया जा सकता है, लेकिन इसमें 'इसके बजाय प्रयास करें" भी शामिल होना चाहिए। । "
जोएल

edहै हमेशा क्योंकि एक जवाब, edमानक पाठ संपादक है।
मिठाई

5
@ubashu हालांकि यह एक grepजवाब नहीं है , "आप इसे एक्स के साथ नहीं कर सकते, लेकिन आप इसे वाई के साथ कर सकते हैं, यहाँ कैसे" अभी भी एक वैध जवाब है क्योंकि आप न केवल ओपी के सवाल का जवाब देते हैं, बल्कि आप एक विकल्प भी प्रदान करते हैं इससे काम बन जाएगा। यह एक मान्य प्रकार का उत्तर है।
थॉमस वार्ड

5
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile

यहाँ हम awk के फंक्शन का उपयोग बाहरी कमांड को कॉल करने के लिए करते हैं, जो कि प्रिंट से पहले और बाद में 5 वें लाइनों के साथ पैटर्न के साथ मेल खाती हुई awk को प्रिंट करता है ।system(command)sedmatch

वाक्यविन्यास आसान है, आपको बस बाहरी कमांड को दोहरे-उद्धरण के साथ-साथ इसके स्विच के अंदर रखना होगा और उन चीजों से बचना चाहिए जो आप ठीक से कमांड को पास करना चाहते हैं, बाकी awkविकल्पों से संबंधित सब कुछ उद्धरणों के बाहर होना चाहिए। तो नीचे सेड :

"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME

में अनुवाद:

sed -n "NR-5p; NRp; NR+5p" FILENAME

NRलाइन नंबर है जो पैटर्न के साथ मेल खाता है matchऔर FILENAMEवर्तमान प्रसंस्करण फ़ाइल नाम से गुजर रहा है awk


2

@ ग्लेन के उदाहरण पाठ फ़ाइल का उपयोग करना और awk के बजाय पर्ल का उपयोग करना:

$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex

एक ही परिणाम देगा, लेकिन तेजी से चल रहा है:

a
f match
k
d
i match
n

João, आप LQ की समीक्षा कतार में दिखाई दे रहे हैं और @waltinator ने हटाने के लिए मतदान किया है, इसलिए अगली बार एक छोटी सी क्रिया अधिक करें ... ;-) इसके अलावा LQ कतार से बाहर निकलने के लिए +1 ... : P
Fabby

1
@JJoao कम गुणवत्ता की समीक्षा कतार। आपका उत्तर संभवतः वहां मिला क्योंकि यह 90% कोड था।

1
@ जेजो 90% का आंकड़ा इसे समझाने का मेरा तरीका है। मुझे नहीं पता है कि वास्तव में किन आंकड़ों का उपयोग किया जाता है।
१j '४१ बजे वंडारे

1
मेनोस कैफ़े, माई एसक्रिटा! @ जोजो : डी ;-): डी
फैबी

1
@ फैबी: सेम कैफे नाडा फंकियोना: डी - शायद यह LCQ (= कम कॉफी कतार) में दिखाई देगा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.