एक स्ट्रिंग के लिए खोजें और एक सीमा के भीतर और बाद में सब कुछ प्रिंट करें


9

मेरे पास यह फाइल है:

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

मैं एक विशिष्ट स्ट्रिंग के लिए इस फ़ाइल को खोजना चाहता हूं और इस स्ट्रिंग से पहले सब कुछ प्रिंट करना चाहता हूं {और इस स्ट्रिंग के समापन के बाद सब कुछ }। मैंने इसे sed के साथ हासिल करने की कोशिश की, लेकिन अगर मैंने श्रेणी में सब कुछ प्रिंट करने की कोशिश की, तो /{/,/string2/यह sed प्रिंट करता है:

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

अगर मैं स्ट्रिंग "string2" की खोज करता हूं, तो मुझे आउटपुट की आवश्यकता है:

sometext2{
string2
string3
}

धन्यवाद।


खैर, अब मैंने पाया कि मुझे बाद में हटाने के लिए मूल फ़ाइल में ouput की पंक्ति संख्याओं की आवश्यकता है। मैंने कमांड बदलने की कोशिश की कि @mikeserv बिना किसी भाग्य के आपूर्ति करता है, मैं sed के होल्ड फ़ंक्शन के साथ थोड़ा भ्रमित हूं।
कृपालु

ठीक है, गीज़, रोड्रिगो, तुमने किसी को नहीं बताया, लेकिन खुद को। यह किया जा सकता है, लेकिन यह सबसे अच्छा किया जाता है grep -n '' <infile | sed ...sedआदेशों बदलाव की आवश्यकता होगी; विशेष रूप से /एड्रेस /बिट्स जो ^टॉप-ऑफ-लाइन एंकर की तलाश में हैं। इसलिए, यदि आप मेरे उत्तर का उपयोग कर रहे थे तो आप शायद कर सकते थे grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d':। सभी आउटपुट लाइनों को मूल फ़ाइल की पंक्ति संख्याओं के साथ उपसर्ग किया जाएगा 1:sometext1{\n2:string1और उसके बाद एक कॉलोन जैसे और इतने पर। sedकेवल वही फ़िल्टर करेगा जो पहले फ़िल्टर करेगा, सिवाय इसके कि प्रत्येक आउटपुट लाइन एक संख्या के साथ खुलती है।
मिकसेर्व

जवाबों:


9

यहाँ दो आज्ञाएँ हैं। यदि आप एक ऐसी कमांड चाहते हैं, जो अंतिम .*{$पंक्ति तक एक अनुक्रम में हो (जैसा कि @don_crissti करता है ed) आप कर सकते हैं:

sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'

... जो करने के लिए हर पंक्ति जोड़कर काम करता है Hएक निम्नलिखित वर्ष अंतरिक्ष \newline चरित्र, अधिलेखन hहर पंक्ति है कि मैचों के लिए पुराने अंतरिक्ष {$, और ing गमागमन hहर पंक्ति के लिए पुराने और पैटर्न रिक्त स्थान है कि मैचों ^}- और इस तरह उसकी बफर निस्तब्धता।

यह केवल उन रेखाओं को प्रिंट करता है जो एक {तत्कालीन \nइवलाइन और फिर PATTERNकिसी बिंदु पर मेल खाते हैं - और यह केवल कभी भी बफर स्वैप के तुरंत बाद होता है।

यह सीरीज़ के {$आखिरी में होने वाले मैचों की श्रृंखला में किसी भी लाइन को समाप्त करता है, लेकिन आप उन सभी को शामिल कर सकते हैं जैसे:

sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'

यह hहर ...{$.*^}.*अनुक्रम के लिए स्वैप पैटर्न और पुराने रिक्त स्थान है , अनुक्रम के भीतर सभी लाइनों को Hएक \newline चरित्र के बाद पुरानी जगह में जोड़ता है, और जो कुछ भी रहता है उसे फिर से शुरू करने से पहले हर पंक्ति चक्र के लिए पैटर्न अंतरिक्ष में Dपहले होने वाली \newline वर्ण तक eletes।

बेशक, \nपैटर्न स्पेस में यह केवल एक ही बार ईविल हो जाता है, जब एक इनपुट लाइन मेल खाती है ^}- आपकी सीमा का अंत - और इसलिए जब यह किसी अन्य अवसर पर स्क्रिप्ट को फिर से चलाता है तो यह केवल अगली इनपुट लाइन में सामान्य रूप से खींचता है।

जब PATTERNएक के रूप में एक ही पैटर्न अंतरिक्ष में पाया जाता है \newline है, हालांकि, यह बहुत इसके साथ अधिलेखित से पहले प्रिंट ^}फिर से (इसलिए यह सीमा समाप्त करने और बफर फ्लश कर सकते हैं)

इस इनपुट फ़ाइल को देखते हुए (धन्यवाद डॉन) :

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}
}

पहला प्रिंट:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

...और दूसरा...

sometext2{
PATTERN
string3
}
Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

@don_crissti - मुझे पता नहीं। यह केवल उस रेखा के अनुक्रम को परिसीमित करता है जिसकी शुरुआत होती है }। यह इस तरह के लिए फायदेमंद हो सकता है ... open{\nsub;\n{ command; }\n}; close- लेकिन मुझे यकीन नहीं है कि यहाँ क्या हो रहा है ...
mikeserv

हाय @mikeserv - मैं इसी तरह का सवाल उठाता हूं जो यहां उठाया गया है unix.stackexchange.com/questions/232509/… , आपका समाधान छोटी फाइल पर काम करता है, लेकिन मेरे पास एक बड़ी फाइल है और मुझे "होल्ड स्पेस ओवरफ्लो" हो रहा है। त्रुटि संदेश। कोई भी मौका आपको पता है, मैं इसे कैसे हल कर सकता हूं? बहुत धन्यवाद
नारायण अखाडे

@ नारायणअखड़े - नहीं। एक ओवरहाल के बिना, वैसे भी नहीं। जब तक ... इनपुट के बड़े विस्तार हैं जो {...}ब्लॉक के साथ समाहित नहीं हैं ? अगर ऐसा है और आप पहले समाधान का उपयोग कर रहे हैं, तो आप /{$/,/^}/Hबस के बजाय शुरू में कर सकते हैं H। लेकिन अगर आपने दूसरा समाधान भी आजमाया और फिर भी उसी त्रुटि का सामना करना पड़ा, तो इसकी मदद करने की संभावना नहीं है क्योंकि वह पहले से ही ऐसा करता है। और छूट भी नहीं ed। डॉन को यहां बहुत अच्छा जवाब मिला है, और edअस्थायी बफर फ़ाइलों का उपयोग करने के लिए बहुत ही सरल रूप से लागू किया जा सकता है , जो मेम बफर ओवररन को रोकना चाहिए।
15

6

यहाँ एक समाधान के साथ है ed:

ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'

अर्थात्:

g/PATTERN/     # mark each line matching PATTERN  
?{?,/}/p       # for each marked line, print all lines from the previous { up to the next }  
q              # quit editor

यह मानता है कि PATTERNप्रत्येक जोड़ी के बीच केवल एक ही रेखा है { }अन्यथा आपको प्रत्येक अतिरिक्त पंक्ति के PATTERNलिए उसी ब्लॉक के अंदर डुप्लिकेट आउटपुट मिलेगा ।
यह { }एक एकल पंक्ति से मेल खाने वाले एकाधिक के लिए काम करेगा PATTERNजैसे PATTERNदो अलग-अलग वर्गों में एक परीक्षण फ़ाइल के लिए :

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN again

another string here
}
}

चल रहा है

ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'

आउटपुट:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN again

another string here
}

मैंने इससे बहुत कुछ लिया, वास्तव में! बहुत बहुत धन्यवाद!
15

मुझे यह भी नहीं पता कि यह आदेश मौजूद है। धन्यवाद
रॉड्रिगो

4

के साथ pcregrep:

pcregrep -M '(?s)\{[^}]*PATTERN.*?\}'

या GNU के साथ grepइनपुट प्रदान करता है जिसमें NUL बाइट्स नहीं हैं:

grep -Poz '.*(?s)\{[^}]*PATTERN.*?\}'

0
$ awk 'BEGIN{RS="\n\n"; FS="[{}]"} {if ($2 ~ /string4/) {print $2}}' t1.txt
string4
string5
string6

कहाँ पे:

  • string4 -> स्ट्रिंग का मिलान किया जाए
  • t1.txt -> क्वेरी में उल्लिखित फ़ाइल सामग्री शामिल है

-2

sed -n '/ string / p' फ़ाइल नाम

-n जब sed में मिलाया जाता है, तो sed के sed के डिफ़ॉल्ट व्यवहार के साथ यह कथन आपको वह नहीं दे सकता है जो आप चाहते हैं, लेकिन यह केवल स्ट्रिंग को विस्थापित करना चाहिए

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