Her ikinci satırı bir dosyadan nasıl silebilirim?


25

Dosya:

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

Beklenen çıktı dosyası:

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

Çıktının bu şekilde görünmesini istiyorum: her ikinci satır silinecek ancak satırlar arasında boşluk kalmayacaktır.


5
Her ikinci satırı veya "Hata oluşmadı" içeren tüm satırları silmek istiyor musunuz ? İki ardışık satırda "Hata oluşmadı" varsa ne olur ?
Tulains Córdova

1
@ user1598390 Bence ... bu durumda grep -v "No error occurred" filebu komut işe yaramalıydı ... ne @paul cevap verdi. Çıktı dosyasında, bu kısımda "Hata oluşmadı" içeren bir satır bulunmayacak.
pmaipmui

1
O zaman sorunun başlığı yanıltıcıdır.
Tulains Córdova

Yanıtlar:


36

İle sed:

sed -e n\;d <file

POSIX ile awk:

awk 'FNR%2' <file

Eğer yaşınız büyükse awk(beğenilirse oawk):

oawk 'NR%2 == 1' <file

İle ex:

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

dosyayı yerinde düzenler.

  • g global bir komutu işaretle
  • /$/ her çizgiyle eşleş
  • +d sonraki satırı sil
  • wq! tüm değişiklikleri kaydet

Bu yaklaşım yaklaşımla aynı ideali paylaşır, sedmevcut satırın her satırını satır 1'den başlar.

İle perl:

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

ve perl6:

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

Evet ... çalışıyor ... :) ... ilki çalışıyor .... ikincisini de denedim .. `awk: sözdizimi hatası satır1 awk: satır 1 '' e doğru
sızıyor

sed -en \ d <dosya ~ Evet çalışma @cuonglm ...
pmaipmui

1
Değerli bir karakter kaydetmek n\;dyerine kullandığınızı tahmin ediyorum 'n;d'ama gereksiz yere -eanahtar ve dosya yönlendirmesini kullandığınızda bu mantık pencereden çıkıyor <!
Tom Fenech,

1
@Geek: Bu sadece daha kısa bir versiyonudur sed -e 'n;d', size bir karakter kazandırır.
cuonglm

1
@Geek: nkomut -nkullanılmışsa standart çıktıya desen yazma komutunu verin , ardından desen boşluğunu bir sonraki satırla değiştirin. İşte her tek satır satır tarafından basılacak n, hatta satır sonra desen alanına okunacak ancak dkomutla derhal silin .
cuonglm

62

Bunu, her ikinci satırı silerek çözmek, hataya açık olabilir (örneğin, işlem bazen bir yerine iki anlamlı satır oluşturduğunda). Çöpü filtrelemek daha iyi olabilir:

grep -v "No error occurred" file

Filtre olarak çalıştırılabilir, burada daha fazla çöp deseni ekleyebilir ve sonucu iyileştirebilirsiniz.


9
İkinci satırın bazen önemli olduğunu vurgulamak için +1!
Kaz Wolfe,

12

GNU ile soruya cevap sed:

sed '0~2d' file

her ikinci satırı silecek ancak içeriğine göre filtre satırları sunmak istiyorum:

sed '/Data/! d' file

veya aynı sonuçla

sed '/No error/d' file

sed '/ Hata yok / d' dosyası ~ istenen çıktıyı verir @Costas
pmaipmui 10

5
Son ikisinin yazmanın kıvrımlı yolları olduğuna dikkat edin grep Datavegrep -v 'No error'
Stéphane Chazelas 4:15

5

İşte kullanarak bir yoludur sed:

sed -n 'p;n' filename

GNU ile başka bir yol sed:

sed -n '1~2p' filename

Yukarıdaki komutlardan çıktı alın:

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

Ne demek istiyorsun shortest way using sed?
cuonglm, ağustos

Komuttaki sebep nedir g? sed -n 'p;n'yeterlidir.
Costas,

@cuonglm: Yapmanın basit bir yolunu söylemek istiyorum. Bu arada bu kelimeyi kaldırdık. :)
serenesat

@Costalar: Teşekkürler! Sadece kontrol, olmadan çalışıyor g. g komutundan kaldırıldı. :)
serenesat 3:15

4

İle deneyebilirsiniz awk:

awk 'NR % 2 != 0' file

veya yalnızca şunları içeren satırları yazdırabilirsiniz Data inserted:

awk '$0 ~ /Data inserted/' file


3

Başka bir cevap, vi / vim kullanabilirsiniz!

qdjddq

Ve sonra dosyanız 500 satır ise (örneğin) yazın

250 @ d

Ve sonra yazın ve çıkmak için yazın

: x

Veya bir şeyler ters giderse ve kaydetmek istemiyorsanız:

: Q!

Açıklama:

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

İşte bunu yapmanın oldukça farklı bir yolu:

< file paste - - | cut -f1

Bu, tek numaralı satırların sekme içermediğini varsayar. Eğer öyleyse, o zaman başka bir ayırıcı karakter seçmeniz gerekir, örneğin ::

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

1
Soruyu ilk gördüğümde aklımdaydı ... sedDevasa bir dosya ile hız testi yapmak ilginç olurdu (örneğin 20 mil satır). Neyse, 1 ama gerçekten, önlemek tipi başağrıları, bir metin dosyasına pek mümkün olan bir sınırlayıcı almak gibi $'\002'...
don_crissti

@don_crissti evet ayırıcı için basılmayan bir karakter kullanılması iyi bir fikirdir. Ve evet, bu sed çözümden ölçülebilir bir şekilde daha hızlı. İle bir test dosyası oluşturdum seq 100000000 > 100mil.txt. paste|cutÇözelti yaklaşık 12 vs, 7.5 saniyede tamamlandı sedçözeltisi. Tekrarlanabilir gibi görünüyor. grepen hızlı olsa da. Standart GNU araçlarıyla Ubuntu 14.04.
Dijital Travma

Evet, paste+ işleri cutiçin yoğun bir şekilde optimize edildi, bu yüzden şaşırtıcı olmayan bir şekilde kombinasyonları oldukça hızlı ...
don_crissti 07:15 '

1

Başka bir seçenek (daha kısa)

sed 'n; d' file

3
Benimkinden daha uzun sed n\;d, ekleme -esadece benim alışkanlığım.
cuonglm

0

Ayrıca biraz yavaş olsa da sorunu çözüyor:

vim -c "%normal jdd" -c "wq" file
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.