लाइन 5 से शुरू होने वाली रिक्त लाइनों को कैसे हटाएं


10

मेरे पास यह है:

sed -i '/^$/d' temp_spec.rb

जो खाली लाइनों को छीन रहा है और अच्छी तरह से काम करता है। मैं इसे केवल 5-999 (या आदर्श रूप से 5 से अंत-फ़ाइल तक) लाइनों के लिए कैसे कर सकता हूं।

मैंने कोशिश की:

sed -n5,999 -i '/^$/d' temp_spec.rb
sed '5,999!d/^$/d' temp_spec.rb

लेकिन न तो काम किया (कोई त्रुटि नहीं)।


बस यह सुनिश्चित करने के लिए: क्या आप लाइनों को 1 से 4 रखना चाहते हैं , चाहे वे खाली हों या नहीं, या क्या आप लाइनों 1 से 4 को हटाना चाहते हैं , कोई फर्क नहीं पड़ता कि वे खाली हैं या नहीं? (अब तक, मैंने पूर्व को मान लिया था, लेकिन आपने जो दूसरा आदेश दिया था, वह मुझे आश्चर्यचकित करता है।)
उवे

जवाबों:


12

यदि आप पंक्ति 5 से शुरू होने वाली सभी रिक्त लाइनों को हटाना चाहते हैं और 1 से 4 की पंक्तियों को रखना चाहते हैं, तो आप उपयोग कर सकते हैं

sed -i '5,${;/^$/d;}' temp_spec.rb

{समूहीकरण ऑपरेटर है, इसलिए पहले आदेश 5,${का अर्थ है "लाइन 5 से इनपुट के अंत तक ( $) मिलान जब तक निम्नलिखित आदेश पर अमल }"। पतों के बीच {और }फिर से पतों से उपसर्ग किया जा सकता है, इसलिए आंतरिक कमांड का /^$/dअर्थ है "यदि लाइन के शुरुआत ( ^) और अंत ( $) के बीच कुछ भी नहीं है , तो इसे हटा दें"। सेड कमांड को अलग किया जा सकता है ;। (यह sed की एक बुरी तरह से प्रलेखित सुविधा है यह सबसे sed कार्यान्वयन के द्वारा समर्थित है, लेकिन यह नहीं है। पूरी तरह से पोर्टेबल नहीं Hauke द्वारा बताया गया है,।) ;के बाद {वैकल्पिक है; पहले }आवश्यक है, हालांकि।

यदि आप पंक्ति 5 से शुरू होने वाली सभी खाली लाइनों को हटाना चाहते हैं और 1 से 4 की लाइनें भी हटाना चाहते हैं, तो यह आसान है:

sed -i '1,4d;/^$/d' temp_spec.rb

अच्छा लगा। मुझे पता नहीं था कि पते इस तरह से नेस्टेड हो सकते हैं। मेरे लिए यह अग्रणी के बिना ;भी काम करता है।
हउक लागिंग

हां, आप पहले के बारे में सही हैं ;
उवे

@ हॉक लैजिंग आप एक सीड स्क्रिप्ट में ';' से कमांड को अलग कर सकते हैं। इसके बजाय उन्हें अलग लाइनों पर रखना। यह एक "अनिर्दिष्ट" सुविधा है।
प्रेड्रैग पुंसोवैक

4

Awk का उपयोग कर एक अन्य विकल्प:

awk 'NR<5||/./'

2
sed '5,${s/^$//; t delete; b end; : delete; d; : end;}' temp_spec.rb

1 संपादित करें:

मैं यह समझा रहा हूँ, इस प्रकार ...

यह अनावश्यक रूप से जटिल है। मुझे पता नहीं था कि पते की सीमाओं के भीतर अनुमति है {}। इसलिए मुझे "खाली लाइनों को अलग" व्यक्त करना पड़ा। कोर कमांड है, tजो सेड का तरीका है if ... thenTआसान होता, लेकिन केवल GNU सेड के लिए उपलब्ध है। मैं आदमी पृष्ठ का हवाला देता हूं:

t लेबल: यदि /// ने अंतिम इनपुट लाइन को पढ़ने के बाद से एक सफल प्रतिस्थापन किया है और अंतिम टी या टी कमांड के बाद से, तो लेबल करने के लिए शाखा; यदि लेबल छोड़ा गया है, तो स्क्रिप्ट के अंत में शाखा।

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

यदि s"प्रतिस्थापन" किया है तो लाइन खाली है। उस स्थिति में आदेश dनिष्पादित किया जाएगा। अन्यथा कुछ नहीं करना है। जैसा कि tएक sकार्रवाई के मामले में नहीं कूदता है मुझे bस्क्रिप्ट के अंत में कूदने के लिए शाखा कमांड की आवश्यकता है । : labelशाखा लक्ष्य हैं। पहले की तरह gotoफिर अंधेरे युग में (जब सेड का आविष्कार हुआ ... ते-ही)।

एक और विकल्प sसभी गैर-खाली लाइनों को "प्रतिस्थापित" करना होगा , जिससे sअधिक जटिल लेकिन बाकी की कमान आसान हो जाएगी:

sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input

^..*$"गैर-रिक्त रेखा" का \1अर्थ है और "पहले कोष्ठक की सामग्री"।


ओपी के लिए थोड़ा सा स्पष्टीकरण (मैं उनके दिमाग को यह पढ़कर कानों के माध्यम से क्रॉल करने की कोशिश कर सकता हूं ...)
वॉनब्रांड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.