2010-10-06 10 views
16

मैं फ़ाइल में मिलान रेखा से पहले और बाद में कई लाइनों को फ़िल्टर करना चाहता हूं।संदर्भ के साथ grep invert खोज

यह पंक्ति है कि मैं नहीं चाहता निकाल देगा:

$ grep -v "line that i don't want" 

और इस से पहले 2 लाइनों प्रिंट होगा और पंक्ति के बाद मैं नहीं करना चाहता:

$ grep -C 2 "line that i don't want" 

लेकिन जब मैं उन्हें गठबंधन करता हूं तो यह लाइन से पहले और बाद में 2 लाइनों को फ़िल्टर नहीं करता है, मैं नहीं चाहता:

# does not remove 2 lines before and after the line I don't want: 
$ grep -v -C 2 "line that i don't want" 

मैं केवल उस पंक्ति को कैसे फ़िल्टर करूं जो मैं नहीं चाहता, बल्कि इसके पहले और उसके बाद की रेखाएं भी? मुझे लगता है कि sed इस के लिए बेहतर होगा ...

संपादित करें: मुझे पता है कि यह अजीब/पर्ल/पायथन/रूबी/आदि की कुछ पंक्तियों में किया जा सकता है, लेकिन मैं जानना चाहता हूं कि एक संक्षिप्त है या नहीं एक लाइनर मैं कमांड लाइन से चला सकता है।

sed 'h;:b;$b;N;N;/PATTERN/{N;d};$b;P;D' inputfile 

आपने हटाने के लिए लाइनों की संख्या को प्रभावित करने के पैटर्न से पहले N आदेशों की संख्या भिन्न हो सकते हैं:

+1

http://superuser.com –

+0

क्या कोई कारण है? – aaronstacy

उत्तर

4

इस आज़मा कर देखें।

आप प्रोग्राम के रूप में एक स्ट्रिंग N आदेशों की संख्या वाले बना सकते हैं:

C=2 # corresponds to grep -C 
N=N 
for ((i = 0; i < C - 1; i++)); do N=$N";N"; done 
sed "h;:b;\$b;$N;/PATTERN/{N;d};\$b;P;D" inputfile 
+1

नहीं, आपका मतलब है 'grep' बस यह नहीं कर सकता है ?! क्या कोई कारण है?यह मेरे लिए counterintuitive है – n611x007

+0

@naxa: जब '-C' और' -v' का उपयोग किया जाता है तो '-C' में अतिरिक्त लाइनों को छोड़कर बाहर की गई रेखाएं शामिल होती हैं। इसे आज़माएं: 'printf '% s \ n' {1..36} | grep --color -C 2 -v '^ 2.' 'और आप देखेंगे कि 20, 21, 28 और 2 9 को 18, 1 9, 30 और 31 को छोड़कर शामिल किया गया है। '-C' विकल्प को POSIX द्वारा निर्दिष्ट नहीं किया गया है। –

+1

आह मैं देखता हूं। आपकी चिंता के लिए बहुत बहुत धन्यवाद और अब रंग में अच्छा उदाहरण! मैंने -ए और -बी के साथ प्रयास किया है लेकिन वे समान रूप से काम करते हैं-सी। वे अब भी 'गैर-पॉजिक्स' प्रतीत होते हैं जो मुझे पता है कि मुझे क्या देखने के लिए याद आया। – n611x007

1
awk 'BEGIN{n=2}{a[++i]=$0} 
/dont/{ 
    for(j=1;j<=i-(n+1);j++)print a[j]; 
    for(o=1;o<=n;o++)getline; 
    delete a} 
END{for(i in a)print a[i]} ' file 
+0

मुझे पता है कि आप शायद पहले से ही यह जानते हैं क्योंकि आपके पास मुझसे अधिक एक्सपी है, लेकिन आप शायद कोड सेगमेंट की तुलना में थोड़ा अधिक स्पष्टीकरण जोड़ना चाहें, इस तथ्य को संबोधित करते हुए कि ओपी ने एक grep समाधान की मांग की, जबकि पेशकश आपका अन्यथा बहुत मान्य और बेहद उपयोगी एडब्ल्यूके समाधान। धन्यवाद! –

+0

@ डर्मोट कैनिफ़ेफ़, स्वीकार किए गए उत्तर को sed का उपयोग करके और भी गड़बड़ कर दिया गया है। – ghostdog74

+0

काफी सच है। जितना ज्यादा मुझे प्यार है, मुझे लगता है कि अजीब प्रक्रियाओं को खोजना बहुत आसान है। :) –

2

लाइनों सभी अद्वितीय आप लाइनों आप एक फ़ाइल में निकालने के लिए, और फिर उस फ़ाइल का उपयोग दूर करने के लिए करना चाहते हैं grep सकता है कर रहे हैं मूल से लाइनें, उदाहरण के लिए

grep -C 2 "line I don't want" <A.txt> B.txt 
grep -f B.txt A.txt 
0

मुझे लगता है कि @ fxm27 में उत्कृष्ट, बाश-वाई उत्तर है।

मैं जोड़ता हूं कि अगर आप अगली पंक्तियों के पैटर्न को पहले से जानते थे तो आप egrep का उपयोग करके इसे एक और तरीके से हल कर सकते हैं।

command | egrep -v "words|from|lines|you|dont|want" 

यह एक "समावेशी या" क्या करेंगे, जिसका अर्थ है कि एक लाइन है कि किसी भी उन लोगों में से से मेल खाता है बाहर रखा जाएगा।

0

मैंने इसे दो अनुक्रमिक grep के साथ हल किया, वास्तव में। ऐसा लगता है कि मेरे लिए रास्ता अधिक सरल है।

grep -C "match" yourfile | grep -v -f - yourfile 
संबंधित मुद्दे