2010-12-14 11 views
6

मैं केवल लाइन के विशिष्ट हिस्सों पर कैसे काम कर सकता हूं? और, इसके विपरीत, मैं एक लाइन के विशिष्ट हिस्सों पर कैसे काम नहीं कर सकता?लाइन के हिस्से पर कैसे काम करें

उदाहरण:

"A a A a (A a) A (a A) a" 

मैं कैसे, उदाहरण के लिए, सभी A रों T रों साथ ( और ) के बीच केवल प्राप्त करने के लिए स्थान लेते हैं:

"A a A a (T a) A (a T) a" 

और दिए गए अगले उदाहरण इनपुट:

"F f F f (F f) F (f F) f" 

मैं कैसे, उदाहरण के लिए, सभी F रों X रों नहीं बल्कि ( और ) के बीच के साथ को प्राप्त की जगह है:

"एक्स एफ एक्स च (एफ एफ) एक्स (एफ एफ) एफ "

मैंने Google की खोज की लेकिन मुझे कुछ भी उपयोगी नहीं मिला। मुझे लगता है कि यह sed के बारे में एक सामान्य सवाल है। समस्या सामान्य sed "टेम्पलेट्स" के लिए कमजोर है, मुझे उम्मीद है।

  1. से होने और उसके बाद ही
  2. से होने और उन दोनों के बीच की तुलना में कहीं और संचालित करने के लिए (दी लाइन पर सभी घटनाओं पर) उन दोनों के बीच संचालित करने के लिए ...
  3. विशेष मामला जब FROM और TO हैं एक ही (के बीच "और" या "foo" और "foo" आदि) दोनों 1. और 2.

यह मुद्रण आदि, जैसे के साथ किसी भी आपरेशन ही नहीं, प्रतिस्थापन साथ काम करना चाहिए, लेकिन यह भी के लिए तार में "फू" और "बार" तारों के बीच सबकुछ प्रिंट करना।

"1 2 3 BAR a b c FOO d e f BAR g a h FOO i j k BAR l m n FOO o p q" 

परिणाम होगा

" d e f i j k " 

इसलिए, यह कैसे करना है पर सामान्य उदाहरण अत्यधिक सराहना की जाएगी। ऐसा लगता है कि यह सवाल काफी आम है, लेकिन Google पर अभी तक कोई अच्छा नहीं पाया गया है। मुझे यह भी लगता है कि यह उत्तर देने के लिए काफी चुनौतीपूर्ण होगा। कृपया, पर्ल, एडब्ल्यूके या sed के अलावा जो भी कुछ भी को कैसे करें, इस पर कोई संकेत न दें। यह सवाल वास्तव में एक केवल एकमात्र सवाल है।

+0

मैंने अपनी पूरी कोशिश की। मेरा विचार था कि रेखा को और से (किसी भी तरह) और फिर "किसी भी तरह" (मुझे अभी तक नहीं पता) द्वारा टुकड़ों में विभाजित करना था या तो केवल या अजीब हिस्सों को या तो कुछ या समान रूप से संचालित करना था। अगर मुझे पता था कि यह कैसे करना है, तो मैं यहां नहीं पूछूंगा। और, यह संभावना है कि विभाजन का मेरा विचार गलत हो सकता है। यह काफी मुश्किल है और मैं पहले ही सरल कार्यों के लिए sed का उपयोग करता था। – mjf

उत्तर

1

विभाजित करें और जीतें।

सम्मिलित नई-पंक्तियों एंकरों और लूप के रूप में, अलग करने के लिए खंडों तो नई-पंक्तियों का उपयोग करें, लाइन शुरुआत (^) लाइन समाप्त होने ($) और सीमांकक वर्ण (इस मामले में कोष्ठकों)। अंत में जोड़े गए न्यूलाइन हटा दिए जाते हैं।

$ echo "A a A a (A a) A (a A) a" | 
    sed 's/([^)]*)/\n&/g; 
     :a; 
      s/\(\n([^)]*\)A\([^)]*)\)/\1T\2/; 
     ta; 
     s/\n//g' 
A a A a (T a) A (a T) a 
$ echo "F f F f (F f) F (f F) f" | 
    sed 's/(/\n(/g; 
     s/)/)\n/g; 
     :a; 
      s/\([^(]*\)F\([^)]*\(\n\|$\)\)/\1X\2/g; 
     ta; 
     s/\n//g' 
X f X f (F f) X (f F) f 
$ echo "1 2 3 BAR a b c FOO d e f BAR g a h FOO i j k BAR l m n FOO o p q" | 
    sed 's/^/BAR/; 
     s/$/FOO/; 
     s/FOO/&\n/g; 
     s/BAR/\n&/g; 
     s/BAR[^\n]*\n//g; 
     s/[^\n]*FOO\n//g; 
     s/\n//g' 
d e f i j k 
+0

धन्यवाद। कृपया मुझे इसके माध्यम से जाने के लिए कुछ समय दें। – mjf

+0

क्या होगा यदि मैं प्रतिस्थापित करना चाहता हूं, कहूं, "[" और "]" वर्णों से घिरे हुए सब कुछ खंड नियमित रूप से अभिव्यक्ति में हैं? यह कार्य सामान्य रेगेक्स को बदलने के समान है (जहां सभी "() [] {} | +?" चरित्र से बचने की कोई आवश्यकता नहीं है) कहें, grep या sed अभिव्यक्ति, जहां विशेष वर्ण बच जाना चाहिए। मेरा मतलब है, दिया गया है, कहें, अगली sed अभिव्यक्ति उन पात्रों से बचने के बिना, जो उन्हें विशेष पात्र बनाने के कारण sed वाक्यविन्यास में भाग गए होंगे, मैं अगली कक्षा के कार्यक्रम के दौरान एरोन्ड स्पेस पर आवेदन करना चाहता हूं: "s/\\ ([] [) {} |? +] \\)/\\\ 1/जी "। इनपुट वही होगा "(/] [() {} | +?])/\\\ 1/g"। – mjf

+0

मैं बेसिक पॉज़िक्स रेगेक्स के रूप में डेटाबेस को बनाए रखता हूं जहां "^। [$() | * +? {\" वर्णों को "गैर-विशेष" (मैन 7 रेगेक्स) बनाने के लिए \ "से बचने की आवश्यकता है"। मुझे इन नियमित अभिव्यक्तियों को एक रूप में बदलने के लिए एक स्क्रिप्ट की आवश्यकता है जिसे मुझे दिए गए पल में चाहिए, grep (1) फॉर्म कहें। तो मुझे इसकी आवश्यकता है, कहें, sed (1) फॉर्म, या vi संपादक फॉर्म इत्यादि। मैन्युअल रूप से रेगेक्स को बदलने से दर्दनाक होता है और अब डीबी काफी बड़ा आकार में उग आया है। सभी regexes मैन्युअल रूप से बदलने के लिए, vi के रूप में ऐसे चालाक संपादक में भी दर्दनाक है। मुझे उस कार्य के लिए एक स्क्रिप्ट चाहिए, जो इस सवाल पूछने के लिए मेरी मूल प्रेरणा थी। – mjf

1

आप (जीएनयू एसईडी) के लिए यह काम कर सकते हैं:

sed ':a;s/\(([^)]*\)A/\1T/;ta' file # for case 1 

sed ':a;s/\(([^)]*\)F/\1\n/;ta;y/F\n/TF/' file # for case 2 

मामले 1 उपयोग एक पाश s 'T को रों अंदर कोष्ठक' A स्थानापन्न करने के लिए।

मामले 2 के लिए ऊपर के रूप में ही उपयोग करें 'नई-पंक्तियों को रों अंदर कोष्ठक, तो अनुवाद कर F' F बदलने के लिए क्रमश: X की और F के लिए और नई-पंक्तियों।

केस 3 एक छोटे से अधिक शामिल है, लेकिन 2 विकल्प आदेशों में किया जा सकता:

sed -r 's/FOO|BAR/\n&/g;s/[^\n]*(\nBAR[^\n]*)*(\nFOO([^\n]*)\nBAR)?(\nFOO[^\n]*$)?/\3/g' file 

पहले उपसर्ग नई-पंक्तियों के साथ प्रत्येक FOO और BAR तार। फिर FOO और BAR के सभी संयोजनों को देखें और केवल FOO और BAR के बीच तारों को रखें। नई लाइनें प्रक्रिया को सरल बनाने के लिए नकारात्मक वर्ग के उपयोग की अनुमति देती हैं।

संबंधित मुद्दे