Sed 'double' newline karakterlerini kaldırabilir mi?


25

Çok fazla boş satır içeren bir belgem var.

Birlikte 2 veya daha fazla olduğunda onları nasıl kaldırabilirim.

sed "s/\n\n//"Dosyayı denedim ama işe yaramadı. Hata yok.


3
Tüm boş satırları kaldırmak istemiyorsanız, ancak iki veya daha fazla olması durumunda sizi doğru okudum. Yani tek boş satır değil mi?
Runium

1
Ve eğer iki ya da daha fazla satır gerçekten hepsi silinecek mi yoksa sadece biri hariç mi?
Hauke ​​Laging

Yanıtlar:


42

Sadece boş satırları kaldırmak için:

sed  '/^$/d'

sedSatır yönelimlidir, bu nedenle baytın yeni bir satır olması dışında "belirli bir baytın 2 veya daha fazlası" olarak düşünülmesi işe yarar. O zaman bütün çizgi için işe yarayan bir şey düşünmelisin.


Tabii ki! Basit şıklık için +1.
terdon

2
sed"desen alanı" / "tutma alanı" özelliği ile birkaç çizgiyi işleme kapasitesine sahiptir. Ama bunun çok karmaşık olduğunu hissediyorum. ;-)
Hauke ​​Laging

Dosyanın ilk karakteri yeni bir satırsa bu istediğiniz gibi çalışmaz.
Chris Down,

1
O (yani gerçekten bir gereklilik ise) ilk karakter bir satır olduğunda geçerli olmasını sağlamak için o zaman bir negatif adresi ile komutunu çevreleyebileceğim 1!böylece (hat 1 hariç tüm maç),: sed '1!{/^$/d'}.
Toby Speight

1
@AaronFranke - evet, ama bu Linux kabukları '>' yönlendirmesini nasıl ele aldığının bir yönü. Kabuk komut satırına bakar, '>' stdout'un bir dosyaya yönlendirmesini görür, o dosyayı oluşturur ve sonra çalışır sed. Bir dosya oluşturmak, esas olarak aynı ada sahip herhangi bir dosyayı siler. sed '/^&/d' file.txt > otherfile.txtçalışacak.
Bruce Ediger,

24

Gerek yok sed. grepyapacağım:

grep .

(bu grep, SPC, nokta, bu en az bir karakter içeren herhangi bir satırla eşleşir).

Ayrıca:

tr -s '\n'

(yeni satır karakterlerinin herhangi bir sırasını bir taneye sıkın).

Chris tarafından belirtildiği gibi, her ikisi de eşdeğer değildir, çünkü boş satırların kaldırılması (yukarıdaki ilk çözüm gibi ve buradaki diğer cevapların çoğu), ilk satırın boş olduğu durumda talep edilen yeni satır karakterlerinin sıkma dizileriyle aynı değildir. ilk satırı boş bırakmak için yalnızca bir tane yeni satır karakteri alır .


2
Dosyanın ilk karakteri yeni bir satırsa
Chris Down

7

sedBunun için en iyi araç değildir, çünkü satır bazlıdır ve satır \nsonu karakteri gibi davranırsa bu karmaşıklaşır.@Bruce Ediger'in cevabını görmüş sedolmak iş için mükemmel bir araç olabilir, yine de, işte başka seçenekler:

  1. Perl

    perl -ne 'print if /./' file.txt
    

    veya

    perl -pe '$/=""; s/\n+/\n/;' file.txt 
    

    Teşekkür etmek @ruakh gitmeme yaptı ve okuyanlar bu :

    , $ /

    Giriş kaydı ayırıcı, varsayılan olarak newline. Bu Perl'in bir "çizgi" ne olduğu fikrini etkiler. Boş dizeleri boş dizgeye ayarlanmışsa, boş satırların sonlandırıcı olarak ele alınması da dahil olmak üzere awk RS değişkeni gibi çalışır (boş bir satır boşluk veya sekme içeremez). Çok karakterli bir sonlandırıcıyla eşleşmesi için çok karakterli bir dizeye veya dosyanın sonuna kadar okumak için tanımsız olarak ayarlayabilirsiniz. "\ N \ n" olarak ayarlamak, dosya arka arkaya boş satırlar içeriyorsa, "" ayarından biraz farklı bir şey anlamına gelir. "" Olarak ayarlamak, iki veya daha fazla ardışık boş satırı tek bir boş satır olarak değerlendirir. "\ N \ n" olarak ayarlamak, yeni bir satır olsa bile, bir sonraki giriş karakterinin bir sonraki paragrafa ait olduğunu kabul eder.

  2. gawk / awk

    awk '$1' file.txt
    

    Bu, yayınlanan örnek için işe yarayacak, ancak @ Stephane Chazelas'ın işaret ettiği gibi, ilk alanı "benzeyen" satırları da silecektir 0. Bu daha sağlam:

    awk NF file.txt
    

Perl için perl -pe 's/\n+/\n/ file.txtyapacak, giriş kayıt ayırıcı bu kullanım için önemli değil.
vonbrand

@ vonbrand no perl -peya da perl -neçalışma satır satır. \n+Asla eşleşmeyecektir, çünkü sadece tek bir satıra uygulanır. Bu yüzden bütün dosyayı ayarlamalısınız $/veya kullanmalısınız . -0perl -0pe 's/\n+/\n/' file
terdon

6

Kaldırmak derken ne demek istiyorsun? yinelenen kaldır (bire bir çok boş satır) ya da tümünü kaldırmak?

Çoğaltmayı kaldırmak istiyorsanız, sed yöntemini burada bulabilirsiniz:

sed '$!N; /^\(.*\)\n\1$/!P; D'

uniqKomutu simüle eder .

En iyi seçenek kullanıyor awk:

awk NF <filename>

Bunun bir sedkısmı harika çalışıyor! Bunu en iyi cevap olarak önermek.
Akito,

2

Bu cevapların çoğu için önce sondaki boşlukları kaldırmak gerekir. İki katına çıkan yeni satırların kaldırılması tüm boş satırları kaldırır. (Bunun hakkında düşün).

Kelimenin tam anlamıyla yorumlanması OP "yinelenen boş satır varsa, dosyadaki tüm boş satırların kaldırılmasını" istiyor.

Tipik kullanıcı "sadece kopyalanan boş satırları kaldırmak" istiyor.

Bunu yapmak için, önce sondaki beyaz boşluğu soyun ve tekrar katlayın.

sed  s/[[:space:]]*$// | cat -s

Ve yine de bu, bir üst veya sondaki boş çizgiyi kaldırmaz.


Aşağı oy verildi, ancak bu açıkça çalışıyor mu? Yorum yok ?
mckenzm

1
Soruyu cevapladığın için ... seni tanıttım. =) Her boş satırı sildiğinde Bruce Ediger'in tepkisinin yükseldiğine inanamıyorum . Birisi yinelenen boş satırlar nasıl kaldırılacağı sorarsa, silme herhangi senaryo hayal edemez tüm boş satırlar kabul edilebilir bir çözüm olacaktır. Fakat herneyse. Bu arada, web sitemizde sed'i
Todd Walton

2

Herhangi bir boş satır dizisi için tek bir boş satır tutmak isterseniz, aşağıdakileri yapabilirsiniz:

sed -e '/./b' -e :n -e 'N;s/\n$//;tn'

1
Bu (yanı sıra cat -s) aslında soruyu tam olarak sorduğumda sorduğu şeyi gerçekleştiren tek cevap . (Ve cat -skullanabildiğimden daha iyidir sed -i.)
Matthew

-2

Her ikisini de alan ayırıcınız olarak sed -e 's#\\n\\n#\\n#g' input.file > output.filekullanmayı deneyin /ve regex'inizin bir kısmı sorun olabilir.


2
Sadece bir sırayla çift ve üçlü yeni satırları içeren dosyalarımdan biriyle bir koşuşturma verdi. Benim için hiç çalışmıyor.
SyntaxError

-3

Bu komutu kullanın:

tr -s '\r' '\n'

evet, cevapları benim için işe yaramadı.
miyav

5
AFAIK bu cevap yanlıştır. Silmenizi öneririm.
zuazo

oh, çünkü benim dosyama çok sayıda yeni satır içeriyor ve satır başı gerçekten geri geliyor. 0x0d0a
miyav

2
Aslında, komut satırları pencerenin sonunda tekrar eden satırları kaldırır. İle test et echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'. Komut trtüm çevirecek \riçin \ntüm sıkmak olacak sonra ve \nsadece bir hiç. Bu yüzden çalışır, bunun UNIX için değil, pencereler için geçerli olduğu konusunda ne yapacağından emin değildir.
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.