बैच, sed या awk का उपयोग करते हुए पा सकते हैं


1

फ़ाइल नाम मिलान पैटर्न 1 के साथ हर फ़ाइल में मैं उन लाइनों की खोज करना चाहता हूं जो पैटर्न 2 से शुरू होती हैं, और उन मिलान की गई लाइनों के ऊपर एक नई लाइन में कुछ स्ट्रिंग जोड़ते हैं।

एक सरल उदाहरण के रूप में, मुझे लगता है कि मैं आलू के लिए .txt फ़ाइलों में खोज कर रहा हूँ और मैं ऊपर 'स्पैम' जोड़ना चाहता हूँ, तो फ़ाइल /tmp/blah.txt

hello
potato
world
not potato
bye

में तब्दील हो जाएगा

hello
spam
potato
world
not potato
bye

शेल विज़ार्ड के लिए एक साधारण नौकरी की तरह लगता है, इसे प्राप्त करने का सबसे आसान तरीका क्या है? मैंने कुछ ऐसे टूल को टैग किया है जो मुझे लगता है कि यहाँ सामान्य संदिग्ध होंगे लेकिन मैं अन्य सुझावों के लिए खुला हूँ। बोनस अंक अगर यह मुझे फाइलों को संशोधित करने से पहले एक पूर्वावलोकन अलग दिखा सकता है।


क्या आप "आलू नहीं" से भी मेल खाना चाहते हैं? आपका प्रश्न इंगित करता है कि हाँ, लेकिन आपका वांछित आउटपुट आपको दिखाता नहीं है।
टेराडॉन

क्षमा करें, मैं क्योंकि यह लाइन के शुरू में नहीं था नहीं करना चाहता था
विम

ठीक है, उत्तर संपादित करें।
टेराडॉन

जवाबों:


2

मैं इसे पर्ल में भी करूंगा:

$ for f in *txt; do perl -pne 'print "spam\n" if /^potato/' "$f"; done
hello
spam
potato
world
spam
not potato
bye

-pझंडा कारणों इनपुट फ़ाइल की प्रत्येक पंक्ति मुद्रित करने के लिए पर्ल। -nइसका मतलब है, "लाइन द्वारा इनपुट फ़ाइल लाइन पढ़ें" और स्क्रिप्ट के द्वारा दिए गए लागू -eप्रत्येक पंक्ति के लिए। फिर, स्क्रिप्ट स्वयं ही प्रिंट होगी spamयदि वर्तमान लाइन समाहित है potatoऔर प्रत्येक पंक्ति को प्रिंट करेगी। नतीजा होने spamवाली लाइनों के ऊपर मुद्रित स्ट्रिंग होगी potato

यह केवल नई फ़ाइल को संशोधित किए बिना प्रिंट करेगा। यदि आप मूल फ़ाइल में परिवर्तन करना चाहते हैं, तो उपयोग करें -i:

$ for f in *txt; do perl -i.bak -pne 'print "spam\n" if /^potato/' "$f"; done

जो foo.txt.bakप्रत्येक संसाधित फ़ाइल के लिए नामक एक बैकअप फ़ाइल बनाएगा और परिवर्तनों को लागू करेगा foo.txt


मेरा मानना है कि /potato/किया जाना चाहिए /^potato$/अन्यथा यह भी "नहीं आलू" लाइन से मेल होगा?
ओलिवियर दुलाक

@OlivierDulac ओपी ने कहा "आलू युक्त लाइनें" मैं "आलू नहीं" लाइन से मेल खाना चाहता था।
टेराडॉन

1
@OlivierDulac सही, धन्यवाद, उत्तर संपादित किए गए हैं।
टेराडॉन

2

व्यक्तिगत रूप से मैं शायद इस तरह से कुछ के लिए पर्ल का उपयोग करूंगा, लेकिन आप अकेले में जो चाहते हैं उसे प्राप्त कर सकते हैं:

while read -r line ; do if [[ $line =~ "potato" ]]; then echo spam;  fi;  echo $line; done < file.txt

यदि आप परिणाम को एक नई फ़ाइल में रखना चाहते हैं:

while read -r line ; do if [[ $line =~ "potato" ]]; then echo spam;  fi;  echo $line; done < file.txt > /tmp/outfile.txt

मेरा मानना है कि $line =~ "potato"किया जाना चाहिए $line =~ "^potato$"अन्यथा यह भी "नहीं आलू" लाइन से मेल होगा?
ओलिवियर दुलाक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.