कमांड 'sed; 1? G; h; $? D' फ़ाइल की सामग्री को कैसे रिवर्स करता है?


20

मेरा प्रश्न रिवर्स ग्रैपिंग के इस प्रश्न के लिए इस उत्तरsed में दिए गए -specific समाधान से संबंधित है । / समाधान है कि मैं समझने के लिए असमर्थ हूँ एक पीछा कर रहा है:sedgrep

sed '1!G;h;$!d' file

क्या कोई कृपया इस आदेश को समझ सकता है?

मैं VI (M) के ज्ञान से जानता हूं कि G फ़ाइल की अंतिम पंक्ति को दर्शाता है और यह कि sed में धमाके (!) के बाद एक पते का काम थोड़ा सा होता है जैसे grep -vकि यह कहना है कि यह उस रेखा से मेल नहीं खाएगा। लेकिन ऊपर एक पूरी इनलाइन सेड स्क्रिप्ट के रूप में मेरे से परे है।


3
... बहुत धीरे से ...
mikeserv

1
जैसा कि मौसिकी संकेत देती है। एक ध्यान दें कि यह मुश्किल sedनुस्खा एक फ़ाइल में लाइनों को उलटने के लिए एक अत्यंत अक्षम तरीका (O (n ^ 2/2) जटिलता) है। यह बड़ी संख्या में लाइनों वाली फ़ाइलों के लिए निषेधात्मक रूप से धीमा होगा। अधिक कुशल लाइन-ऑर्डर रिवर्सल विकल्प के लिए tacGNU कोरुटिल्स से देखें ।
अरीफ

जवाबों:


35

यह फ़ाइल लाइन को लाइन से उलट देता है।

sed '1! G; h; $; d' फ़ाइल

सबसे पहले, sedएक पकड़ स्थान और एक पैटर्न स्थान है । हमें उस विशिष्ट कमांड पर ध्यान केंद्रित करने से पहले उनके बीच अंतर करना होगा।

जब sedएक नई लाइन पढ़ता है, तो इसे पैटर्न स्पेस में लोड किया जाता है। इसलिए, हर बार एक नई लाइन संसाधित होने पर वह स्थान अधिलेखित हो जाता है। दूसरी ओर, होल्ड स्पेस पूरे प्रसंस्करण पर सुसंगत है और मूल्यों को बाद में उपयोग के लिए संग्रहीत किया जा सकता है।


आदेश के लिए:

इस बयान में 3 आदेशों हैं: 1!G, hऔर$!d

  • 1!Gइसका मतलब है कि Gकमांड को पहले एक ( !नेगेट 1) को छोड़कर हर लाइन पर निष्पादित किया जाता है । Gसाधन करने के लिए संलग्न क्या पैटर्न अंतरिक्ष में पकड़ अंतरिक्ष में है।

  • hहर लाइन पर लागू होता है। यह पैटर्न स्पेस को होल्ड स्पेस पर कॉपी करता है (और इसे ओवरराइट करता है)।

  • $!dपिछले एक को छोड़कर हर पंक्ति पर लागू होता है ( $अंतिम पंक्ति का प्रतिनिधित्व करता है, !इसे नकारता है)। dलाइन (पैटर्न स्पेस) को हटाने के लिए कमांड है।


  1. अब, जब पहली पंक्ति पढ़ी जाती है, sedतो hकमांड निष्पादित करता है । पहली पंक्ति को होल्ड स्पेस में कॉपी किया जाता है। तब इसे हटा दिया जाता है, क्योंकि यह $!स्थिति से मेल खाता है । sedदूसरी पंक्ति के साथ जारी है।
  2. दूसरी पंक्ति स्थिति से मेल खाती है 1!(यह पहली पंक्ति नहीं है), और इसलिए होल्ड स्पेस (जिसमें पहली पंक्ति है) को पैटर्न स्पेस (जिसमें दूसरी पंक्ति है) से जोड़ा जाता है। उसके बाद, पैटर्न स्पेस में, अब दूसरी लाइन है जिसके बाद पहली लाइन है, जिसे एक नई लाइन द्वारा सीमांकित किया गया है। अब, hकमांड लागू होता है (हर पंक्ति में); पैटर्न स्पेस में है कि सभी पकड़ अंतरिक्ष के लिए नकल की है। तीसरा कथन ( $!d) लागू होता है: लाइन को पैटर्न स्थान से हटा दिया जाता है।
  3. चरण 2 अब सभी लाइनों के साथ किया जाता है। हम अंतिम पंक्ति पर जाते हैं।
  4. अंतिम पंक्ति ( $) में चरण 2 के लगभग सभी कार्य किए जाते हैं, लेकिन हटाए गए भाग ( d) में नहीं। sed, जब बिना आह्वान किया जाता है -n, प्रत्येक इनपुट लाइन के लिए प्रसंस्करण के अंत में पैटर्न स्पेस को स्वचालित रूप से प्रिंट करता है। इसलिए, जब हटाया नहीं जाता है, तो पैटर्न स्थान मुद्रित किया जाता है। इसमें अब उलटी क्रम में सभी लाइनें हैं ।

1
@Geek नहीं, hकमांड पैटर्न स्पेस को होल्ड स्पेस पर कॉपी करता है, जो sedअंत तक बना रहता है। स्क्रिप्ट के अंत के बाद सब कुछ साफ हो जाता है, क्योंकि बाइनरी बाहर निकलता है।
अराजकता

2
क्या हम विम के लिए रजिस्टरों की तरह होल्ड स्पेस के बारे में सोच सकते हैं? क्या उन्हें भी गिना जाता है? या उनमें से केवल एक ही है?
गीक

2
@ Geek में sedकेवल एक होल्ड स्पेस है। यह एक चर की तरह है जिसमें कुछ हो सकता है।
अराजकता

1
@ user1717828 यदि हम पहली पंक्ति को प्रिंट नहीं करेंगे, तो संसाधित किया जाएगा। चूँकि sed के साथ आह्वान नहीं है, इसलिए -nहमें अंतिम को छोड़कर हर पंक्ति को हटाना होगा। अंतिम पंक्ति में, सब कुछ पकड़ स्थान से पैटर्न अंतरिक्ष में जोड़ता है। और क्योंकि dकमांड निष्पादित नहीं की जाएगी, लाइन प्रिंट की जाती है (इस लाइन में अब पूरी फाइल उलट होती है)।
अराजकता

1
(1) ओपी का उप-प्रश्न / अवलोकन (टिप्पणी में) है, "इसलिए अंतिम पंक्ति परh कमांड एक नो-ऑप की तरह है।" (अतिरिक्त जोर के साथ, और थोड़ा पैराफ्रेस्ड)। वह सही है; जब इनपुट की अंतिम पंक्ति को संसाधित कर रहा होता है , तो होल्ड स्पेस (पैटर्न स्पेस में इसे जोड़ने के लिए) पढ़ता है, और फिर पैटर्न स्पेस को होल्ड स्पेस पर कॉपी करता है, जिसे फिर से संदर्भित नहीं किया जाता है । हम बस के रूप में अच्छी तरह से कह सकते हैं या । (२) हम कह कर उपयोग करने से बच सकते थे । sedGhsed 'G;$!h;$!d'sed 'G;$!{h;d}'dsed -n 'G;h;$p'
स्कॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.