फाइल से हर दूसरी लाइन को कैसे डिलीट करें?


25

फ़ाइल:

Data inserted into table. Total count 13
No error occurred
Data inserted into table. Total count 45
No error occurred
Data inserted into table. Total count 14
No error occurred
Data inserted into table. Total count 90
No error occurred

अपेक्षित आउटपुट फ़ाइल:

Data inserted into table. Total count 13
Data inserted into table. Total count 45
Data inserted into table. Total count 14
Data inserted into table. Total count 90

मैं चाहता हूं कि आउटपुट इस तरह दिखे: हर दूसरी लाइन हट जाएगी लेकिन लाइनों के बीच कोई अंतर नहीं होगा।


5
क्या आप हर दूसरी पंक्ति या उन सभी लाइनों को हटाना चाहते हैं जिनमें "कोई त्रुटि नहीं हुई है" ? यदि लगातार दो लाइनें "कोई त्रुटि नहीं हुईं" तो क्या होगा?
ट्यूलेंस कोर्डोवा

1
@ user1598390 मुझे लगता है ... उस मामले में grep -v "No error occurred" fileइस कमांड को काम करना चाहिए ... @paul ने क्या जवाब दिया। आउटपुट फ़ाइल में, इस भाग में "कोई त्रुटि नहीं हुई" वाली लाइनें नहीं होंगी।
पेमिपमुई

1
फिर प्रश्न का शीर्षक भ्रामक है।
ट्यूलेंस कोर्डोवा

जवाबों:


36

के साथ sed:

sed -e n\;d <file

POSIX के साथ awk:

awk 'FNR%2' <file

यदि आपके पास पुराना awk(जैसे oawk) है, तो आपको चाहिए:

oawk 'NR%2 == 1' <file

के साथ ex:

$ ex file <<\EX
:g/$/+d
:wq!
EX

फ़ाइल को जगह में संपादित करेगा।

  • g वैश्विक कमांड चिह्नित करें
  • /$/ हर पंक्तियों का मिलान करें
  • +d अगली पंक्ति हटाएं
  • wq! सभी परिवर्तनों को सहेजें

यह दृष्टिकोण दृष्टिकोण के साथ एक ही आदर्श साझा करता है sed, लाइन 1 से चालू लाइन की हर अगली पंक्ति को हटा दें।

के साथ perl:

perl -ne 'print if $. % 2' <file

और perl6:

perl6 -ne '.say if $*IN.ins % 2' <file
perl6 -ne '.say if ++$ % 2' <file

हाँ ... इसका काम ... :) ... पहला काम कर रहा है .... मैंने दूसरा भी आज़माया है। इसके बारे में `अवेक: सिंटैक्स एरर लाइन 1 अकोक: लाइन 1 के पास बॉटिंग आउट '
पैमपमुई

sed -en \? d <file ~ Yes its working @cuonglm ...
pmaipmui

1
मैं अनुमान लगा रहा हूं कि आपने एक कीमती चरित्र को बचाने के n\;dबजाय उपयोग किया था, 'n;d'लेकिन जब आप अनावश्यक रूप से -eस्विच और फ़ाइल पुनर्निर्देशन का उपयोग कर रहे हों तो यह तर्क खिड़की से बाहर चला जाता है <!
टॉम फेनेच

1
@ गीक: यह केवल एक छोटा संस्करण है sed -e 'n;d', जो आपको एक वर्ण बचाता है।
congonglm

1
@ गीक: nकमांड मानक आउटपुट के लिए स्पेस स्पेस लिखता है यदि -nइसका उपयोग किया गया था, तो अगली पंक्ति के साथ पैटर्न स्पेस को बदलें। यहां हर विषम रेखा को मुद्रित किया जाएगा n, यहां तक ​​कि रेखा को फिर पैटर्न स्पेस में पढ़ा जाएगा लेकिन dकमांड ' द्वारा तुरंत हटाएं।
cuonglm

62

हर दूसरी पंक्ति को हटाकर इसे हल करना त्रुटि प्रवण हो सकता है (उदाहरण के लिए, जब प्रक्रिया कभी-कभी एक के बजाय दो सार्थक लाइनें उत्पन्न करती है)। हो सकता है कि कचरे को छानना बेहतर हो:

grep -v "No error occurred" file

यह फिल्टर के रूप में चल सकता है, आप यहां अधिक कचरा पैटर्न जोड़ सकते हैं और परिणाम में सुधार कर सकते हैं।


9
+1 इंगित करने के लिए कि कभी-कभी दूसरी पंक्ति महत्वपूर्ण होती है!
कज़ वोल्फ

12

सवाल का Ассоrding, जीएनयू साथ sed:

sed '0~2d' file

प्रत्येक दूसरी पंक्ति को हटा देगा, लेकिन मैं इसके द्वारा फ़िल्टर लाइनें प्रस्तुत करना चाहूंगा:

sed '/Data/! d' file

या उसी परिणाम के साथ

sed '/No error/d' file

sed '/ no error / d' फ़ाइल ~ वांछित आउटपुट देता है @ कोस्टास
pmaipmui

5
ध्यान दें कि अंतिम दो लिखने के तरीके हैं grep Dataऔरgrep -v 'No error'
स्टीफन चेज़लस

5

यहाँ एक तरीका है sed:

sed -n 'p;n' filename

GNU के साथ एक और तरीका sed:

sed -n '1~2p' filename

उपरोक्त आदेशों से आउटपुट:

Data inserted into table. Total count 13
Data inserted into table. Total count 45
Data inserted into table. Total count 14
Data inserted into table. Total count 90

कहने का मतलब क्या है shortest way using sed?
cuonglm 12

gआज्ञा में क्या कारण है ? sed -n 'p;n'पर्याप्त है।
कोस्टास

@cuonglm: मेरा मतलब है सरल तरीके से करने का। वैसे उस शब्द को हटा दिया। :)
सेरेनेसेट

@ कोस्टस: धन्यवाद! बस जाँच की, इसके बिना काम कर रहा है g। कमांड से जी हटा दिया। :)
सेरेनेसेट

4

आप के साथ कोशिश कर सकते हैं awk:

awk 'NR % 2 != 0' file

या आप केवल उन पंक्तियों को प्रिंट कर सकते हैं जिनमें शामिल हैं Data inserted:

awk '$0 ~ /Data inserted/' file

मैंने आपके दोनों उत्तरों की कोशिश की है और दोनों काम कर रहे हैं ... :)
pmaipmui

3

एक अन्य उत्तर, आप vi / vim का उपयोग कर सकते हैं!

qdjddq

और फिर यदि आपकी फ़ाइल 500 लाइनें (उदाहरण के लिए) टाइप थी

250 @ घ

और फिर लिखने और बाहर निकलने के लिए टाइप करें

:एक्स

या अगर कुछ गलत हो जाता है और आप बचाना नहीं चाहते हैं:

: Q!

स्पष्टीकरण:

q      #Start Recording
 d     #Put the recording into register 'd'
  j    #Move the cursor down
   dd  #Delete the line
     q #Stop recording


250    #Number of repeats
   @d  #Playback the recording in register 'd'.

2

यहाँ यह करने का एक अलग तरीका है:

< file paste - - | cut -f1

यह मानता है कि विषम संख्या वाली पंक्तियों में टैब नहीं होते हैं। यदि वे करते हैं, तो आपको एक और विभाजक चरित्र चुनने की आवश्यकता होगी, जैसे :यहाँ:

< file paste -d: - - | cut -d: -f1

1
जब मैंने पहली बार प्रश्न देखा था तो मेरे मन में यह था ... sedएक बड़ी फ़ाइल (जैसे 20 मिलिट्री लाइन्स) के साथ स्पीड टेस्ट चलाना दिलचस्प होगा । वैसे भी, +1 लेकिन वास्तव में, सिरदर्द से बचने के लिए, एक सीमांकक चुनें, जो किसी पाठ फ़ाइल में होने की संभावना नहीं है, जैसे $'\002'...
don_crissti

@don_crissti सेपरेटर के लिए नॉन-प्रिंटिंग कैरेक्टर का उपयोग एक अच्छा विचार है। और हाँ, यह sed समाधान की तुलना में औसत रूप से तेज़ है। मैंने एक परीक्षण फ़ाइल बनाई seq 100000000 > 100mil.txtpaste|cutसमाधान 7.5 सेकंड के बारे में में समाप्त हो गया, बनाम लगभग 12 के लिएsed समाधान। दोहराने योग्य लगता है। grepहालांकि सबसे तेज है। मानक GNU टूल के साथ Ubuntu 14.04।
डिजिटल ट्रामा

हां, paste+ cutअपनी नौकरी के लिए बहुत अधिक अनुकूलित हैं , इसलिए उनके संयोजन बहुत तेजी से खराब हैं ...
don_crissti


0

यह समस्या को हल करता है, हालांकि यह थोड़ा धीमा है:

vim -c "%normal jdd" -c "wq" file
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.