कैसे sed के साथ लाइन के अंत का पता लगाने के लिए


15

जब अंतिम चरित्र एक नई लाइन का उपयोग कर रहा है, तो मैं केवल प्रतिस्थापन को निष्पादित करने का एक तरीका ढूंढ रहा हूं sed

उदाहरण के लिए:

lettersAtEndOfLine

प्रतिस्थापित किया गया है, लेकिन यह नहीं है:

lettersWithCharacterAfter&

चूँकि sedयह नई कहानियों के साथ अच्छी तरह से काम नहीं करता है, इसलिए यह उतना सरल नहीं है

$ sed -E "s/[a-zA-Z]*\n/replace/" file.txt

इसे किस तरह पूर्ण कर सकते है?

जवाबों:


21

मानक के साथ sed, आपको फ़ाइल से पढ़े गए पाठ में एक नई पंक्ति कभी नहीं दिखाई देगी । ऐसा इसलिए है क्योंकि sedलाइन द्वारा लाइन पढ़ता है, और इसलिए वर्तमान लाइन के पाठ के अंत में कोई नई रेखा नहीं sedहै। दूसरे शब्दों में, sedन्यूलाइन-सीमांकित डेटा को पढ़ता है, और सीमांकक एक sedस्क्रिप्ट को देखने का हिस्सा नहीं है।

नियमित अभिव्यक्तियों का उपयोग कर लाइन के अंत में (या शुरुआत में, उपयोग करके ) लंगर डाला जा सकता है । एक पंक्ति के प्रारंभ / अंत में एक अभिव्यक्ति का एंकरिंग करना इसे वहां पर सटीक रूप से मेल खाने के लिए मजबूर करता है, और न केवल लाइन पर कहीं भी।$^

यदि आप [A-Za-z]*कुछ के साथ लाइन के अंत में पैटर्न से मेल खाते हुए कुछ को बदलना चाहते हैं , तो पैटर्न को इस तरह से एंकरिंग करें:

[A-Za-z]*$

... यह लाइन के अंत में और कहीं और मेल करने के लिए मजबूर करेगा।

हालाँकि, चूंकि कुछ[A-Za-z]*$ भी मेल नहीं खाता है (उदाहरण के लिए, हर पंक्ति के अंत में मौजूद खाली स्ट्रिंग ), आपको किसी चीज़ के मिलान को बाध्य करने की आवश्यकता है , उदाहरण के लिए निर्दिष्ट करके

[A-Za-z][A-Za-z]*$

या

[A-Za-z]\{1,\}$

तो, आपकी sed कमांड लाइन इस प्रकार होगी

$ sed 's/[A-Za-z]\{1,\}$/replace/' file.txt

मैंने -Eयहां स्विच का उपयोग नहीं किया क्योंकि इसकी आवश्यकता नहीं है। इसके साथ, आप लिख सकते थे

$ sed -E 's/[A-Za-z]+$/replace/' file.txt

यह स्वाद की बात है।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
Kusalananda

3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt

या, लंबा जटिल अनावश्यक तरीका:

मुझे पता चला है, यह किया जा सकता है, फिर भी ट्रिक की मदद से, सीड का उपयोग करना। आप पंक्ति के अंत का प्रतिनिधित्व करने के लिए एक और चरित्र प्रदान कर सकते हैं। एक अन्य अस्थायी चरित्र का उपयोग किया जाना है, इस मामले में "` "। लाइन के अंत का प्रतिनिधित्व करने के लिए "~" का उपयोग करें:

tr '\n' '`' <input.txt >output.txt
sed -i "s/`/~`/" output.txt
tr '`' '\n' <output.txt >result.txt

और फिर वास्तविक खोज करने और बदलने के लिए, "~" के बजाय "\ n" का उपयोग करें:

sed -i -E "s/[a-zA-Z]*~/replace/" result.txt

और फिर अन्य लाइनों पर अतिरिक्त चरित्र को साफ करें:

sed -i "s/~//" result.txt

जाहिर है, यह सब एक साथ पाइप किया जा सकता है जिसके परिणामस्वरूप कुछ इस तरह है:

tr '\n' '`' <input.txt | sed -e "s/`/~`/" | tr '`' '\n' | sed -E -e "s/[a-zA-Z]*~/replace/" | sed "s/~//" > result.txt

3
मुझे यकीन नहीं है कि मैं समझता हूं ... आप लाइन के अंत में लंगर क्यों नहीं डालते हैं $? जैसेs/[a-zA-Z]*$/replace/
don_crissti

1
2 अंक: 1) आप \+इसके बजाय बेहतर उपयोग करेंगे *क्योंकि बाद वाला स्ट्रिंग के अंत में शून्य अक्षर की अनुमति देता है ; 2) आप एक चरित्र वर्ग का उपयोग कर सकते हैं [[:alpha:]]। तो:sed 's/[[:alpha:]]\+$/replace/' file
ग्लेन जैकमैन

@glennjackman प्लस से पहले बैकस्लैश क्या है? कि अतिरिक्त चरित्र मैच नहीं होगा?
मैथ्यू डी। शोलेफ़ील्ड

1
-rविकल्प के बिना GNU sed इस नियमित अभिव्यक्ति सिंटैक्स का उपयोग करता है ।
ग्लेन जैकमैन

0

आपके द्वारा पोस्ट किए गए (टूटे हुए) कोड स्निपेट से, आप नई पंक्ति को भी बदलना चाहते हैं। उस स्थिति में, खुद से एंकरिंग करना आपकी मदद नहीं कर सकता। निम्नलिखित एक समाधान है:

sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file

टूटा:

  • /[a-zA-Z]\+$/{} इसका मतलब यह है कि जो भी रेगीज़ से मेल खाता है, उसके लिए जो भी कर्ल के अंदर आता है।
  • रेगेक्स वह है जो एंकरिंग का उपयोग करता है जैसा कि आपके स्वयं के उत्तर में देखा गया है , ग्लेन जैकमैन की टिप्पणियों को ध्यान में रखने के लिए संशोधित किया गया है।
  • कर्ल के अंदर का Nअर्थ है , "अगली पंक्ति को सक्रिय बफर में जोड़ें" (जिसे sed'पैटर्न स्पेस' कहते हैं)
  • अंत में s///बयान आपके आवश्यक प्रतिस्थापन है। अब यह काम करता है क्योंकि पैटर्न स्पेस में दो क्रमिक लाइनें होती हैं और इसलिए नई लाइन इसका एक हिस्सा है।

0

लाइन के अंत का पता लगाने के लिए, $ -sign का उपयोग करें :

लाइन एंकर के अंत के बिना:

sed -n '/pattern/p' file 

लाइन एंकर के अंत के बिना:

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