2012-02-01 12 views
6

मुझे कुछ दर्दनाक काम सौंपा गया है और मैं सोच रहा था कि कोई भी मदद कर सकता है या नहीं।विशाल टेक्स्ट फ़ाइल से टेक्स्ट के स्ट्रिपिंग ब्लॉक

हमारे विक्रेता ने एक एसएनएमपी एमआईबी फ़ाइल (txt) प्रदान की है। दुर्भाग्यवश, इस फ़ाइल का एक बहुत भयानक पुराना है और हमारे निगरानी ऐप के लिए इसे बाहर निकालना होगा।

मैं इसे हाथ से करने की कोशिश कर रहा हूं, लेकिन यह 800,000 से अधिक लाइनों लंबा है, और यह मेरी इच्छा को जीने के लिए तैयार है।

-- /*********************************************************************************/ 
-- /* MIB table for Hardware              */ 
-- /* Valid from: 543.44               */ 
-- /* Deprecated from: 600.3              */ 
-- /*********************************************************************************/ 

Some text 
some text 
Some text 

-- /*********************************************************************************/ 
-- /* MIB table for Hardware              */ 
-- /* Valid from: 543.44               */ 
-- /*********************************************************************************/ 

Some text 
some text 
Some text 

-- /*********************************************************************************/ 
-- /* MIB table for Hardware              */ 
-- /* Valid from: 364.44               */ 
-- /* Deprecated from: 594.3              */ 
-- /*********************************************************************************/ 

यादृच्छिक और विज्ञापन nauseum पर बार-बार

क्या मैं सोच रहा हूँ, एक स्क्रिप्ट है कि होता है:

संरचना कुछ की तरह है

पाठ खोजने "से बहिष्कृत" तो

delete that line, 
delete the preceding 3 lines, 
delete the following one line, 
delete then all following lines until the next 
"-- /*********************************************************************************/" 

क्या यह समझ में आता है? क्या इस तरह की चीज संभव है, या क्या मैं केवल सपना देख रहा हूं?

धन्यवाद!

+1

'Deprecated' से करने के लिए हटाया जा रहा है'/** ... 'काफी आसान है, 3 पिछली लाइनों को हटा रहा है जो कुछ और मुश्किल है। – Kevin

+0

मुझे लगता है कि इसे sed या awk से संभालना होगा _my_ जीने के लिए होगा। पर्ल या कुछ अन्य भाषा जो आपको लाइन सीमाओं के चारों ओर पार्स करने की अनुमति देती है, इस समस्या के लिए बेहतर विकल्प है। –

उत्तर

3

संपादित करें: मुझे एहसास हुआ कि मैंने कुछ बार उठाए जाने के बाद भी आपके प्रश्न को गलत पढ़ा है। मेरी प्रतिक्रिया बंद था! अब यह और अधिक सही होना चाहिए, लेकिन कुछ अतिरिक्त मान्यताओं के साथ। सरल समाधान केवल आपको प्राप्त कर सकते हैं!

यह आपको मदद करने के लिए सक्षम हो सकता है कुछ मान्यताओं के साथ:

cat -s data | awk -vFS='\n' -vRS='\n\n' '/Deprecated from/ { getline; next } 1' 

cat आदेश बस वहाँ अतिरिक्त नई-पंक्तियों बाहर निचोड़ करने के लिए है, तो awk और अधिक आसानी से काम कर सकते हैं। awk के लिए, -vFS='\n' बताता है कि फ़ील्ड को न्यूलाइन द्वारा अलग किया गया है, और -vRS='\n\n' यह बताता है कि रिकॉर्ड्स को दो नई पंक्तियों से अलग किया जाता है। फिर /Deprecated from/ रिकॉर्ड प्राप्त करता है जिसमें वह टेक्स्ट है, और { getline; next } इसके बाद के अगले रिकॉर्ड में पढ़ता है, और इसे आगे बढ़ने का कारण बनता है। 1 निम्न बिंदु तक पहुंचने वाली रेखाओं को मुद्रित करने के लिए एक शॉर्टकट है।

यह समझेंगे निम्नलिखित:

  • सभी टिप्पणी और पाठ ब्लॉक कम से कम एक खाली लाइन द्वारा दोनों तरफ अलग होती है
  • केवल टिप्पणी ब्लॉक और पाठ ब्लॉक समान रूप से बीच-बीच में
  • रहे हैं टेक्स्ट ब्लॉक

में रिक्त रेखाएं नहीं हैं इसलिए यह आपके लिए बिल्कुल सही नहीं हो सकता है। यदि ये धारणाएं ठीक हैं, तो यह awk इस नौकरी के लिए एक अच्छा विकल्प बनाती है, जैसा कि आप देख सकते हैं: स्क्रिप्ट छोटी है!

$ cat -s data | awk -vFS='\n' -vRS='\n\n' '/Deprecated from/ { getline; next } 1' 
-- /*********************************************************************************/ 
-- /* MIB table for Hardware              */ 
-- /* Valid from: 543.44               */ 
-- /*********************************************************************************/ 
Some text 
some text 
Some text 

इसके अतिरिक्त, जैसा कि आप देख सकते हैं, नई लाइनें जो धकेलती रहती हैं।इस सहायता के लिए, आप इस तरह आदेश को संशोधित कर सकते हैं:

$ cat -s data | awk -vFS='\n' -vRS='\n\n' '/Deprecated from/ { getline; next } { printf "%s\n\n", $0 }' 
-- /*********************************************************************************/ 
-- /* MIB table for Hardware              */ 
-- /* Valid from: 543.44               */ 
-- /*********************************************************************************/ 

Some text 
some text 
Some text 
1

यह एक सरल vim मैक्रो है।

  1. फ़ाइल लाओ: a
  2. प्रकार /Deprecated from: दर्ज के बाद (पाठ के लिए खोज करने के लिए) रजिस्टर में मैक्रो रिकॉर्ड करने के लिए $ vim filename
  3. प्रेस q a
  4. 3k (ऊपर जाने के लिए 3 लाइनों)
  5. 4dd (इस लाइन को हटाएं और अगले 3)
  6. d/\*\*\*\*\*\* (स्पलट तक लाइनों को हटाने के लिए)
  7. (यदि आवश्यक हो) प्रेस dd (वर्तमान लाइन को हटाने के लिए) मैक्रो रिकॉर्डिंग समाप्त करने के लिए
  8. प्रेस q

  9. प्रकार [email protected] (मैक्रो एक लाख गुना निष्पादित करने के लिए)

1

मैं इसे हल करने के लिए एक और स्क्रिप्टिंग भाषा का उपयोग करने के बारे में टिप्पणी से बहुत अधिक सहमत हैं। रूबी, पर्ल, या पायथन शायद बेहतर होगा। लेकिन मस्ती के लिए, यहां एक बदसूरत Awk स्क्रिप्ट है जो यह करता है। अगर वे उचित नहीं हैं तो मैच शायद कुछ काम का उपयोग कर सकते हैं। लेकिन एक साधारण राज्य मशीन लागू करता है। यह ट्रैक करता है अगर यह हेडर में है या नहीं और यह निर्धारित करता है कि यह बहिष्कृत है या नहीं। यह एक सरणी में हेडर लाइनों को स्टोर करता है। जब यह हेडर के अंत तक पहुंच जाता है, तो यह हेडर प्रिंट करता है (यदि बहिष्कृत नहीं किया गया है)। जब शीर्षलेख में नहीं होता है, तो पिछले अनुभाग को बहिष्कृत नहीं किया गया था, तो यह लाइनों को प्रिंट करता है।

{ 
    if ($0 ~ /-- \/\**+\//) { 
     # This matches one of the -- /*********...****/ lines 
     if (headercount > 0) { 
     # this must be the closing line in the header 
     if (!deprecated) { 
      for (i = 0; i < headercount; i++) { 
       print headers[i] 
      } 
      # print closing line 
      print 
     } # if not deprecated 

     headercount = 0 
     } 
     else { 
     # must be starting a new section 
     headers[0] = $0 
     headercount = 1 
     deprecated = 0 
     } 
    } 
    else { 
     if (headercount == 0) { 
     # not in a header section - print if not deprecated 
     if (!deprecated) { 
      print 
     } 
     } 
     else { 
     # in a header section - track if it is a deprecated section 
     if ($0 ~ /Deprecated from/) { 
      deprecated = 1 
     } 
     # store the header info to dump when we hit the end 
     headers[headercount++] = $0; 
     } 

    } 
} 
2

यह आप के लिए काम कर सकते हैं:

sed '$!N;$!N;:a;$q;N;/Deprecated from/!{P;s/^[^\n]*\n//;ba};$d;$!N;$d;s/.*//;:b;$d;N;/^\n-- \/\*\+\/$/!{s/.*//;bb};D' file 

यहाँ एक से थोड़ा आसान समाधान है (कम कुशल के रूप में यह 2 गुजरता लेता है):

awk '/Deprecated from/{a=NR-3;getline;next};a>0 && /^-- \/\*+\/$/{b=NR-1;print a "," b "d";a=b=0};END{if(a>0)print a ",$d"}' file | 
sed -f - file 
+0

मैं काम करने के लिए इतना बुरी तरह से चाहता हूं, लेकिन यह मेरे लिए नहीं है। मुझे कुछ भी मुद्रित नहीं मिलता है। –

+0

@DanFego ओह! एक डीबगिंग सहायता छोड़ दी। इसे हटा दिया, पुनः प्रयास करें। – potong

+1

यह अक्षरों और प्रतीकों का गन्दा झटका है, लेकिन यह मेरे लिए काम करता है! –

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