Sed kullanarak boş satırları silme


351

Sed kullanarak boş satırları silmeye çalışıyorum:

sed '/^$/d'

ama onunla hiç şansım yok.

Örneğin, şu satırlarım var:

xxxxxx


yyyyyy


zzzzzz

ve şöyle olmasını istiyorum:

xxxxxx
yyyyyy
zzzzzz

Bunun kodu ne olmalı?


2
sed komutunuz iyi görünüyor, işe
yaramalı

Yukarıdaki komut, boşluk / sekmeniz olmasa bile CR + LF satır sonları olsa bile çalışmaz .
devnull

Yanıtlar:


628

"Boş" satırınızda boşluklar veya sekmeler olabilir. Kullanım POSIX sınıfları ile sedsadece boşluk içeren tüm satırları kaldırmak için:

sed '/^[[:space:]]*$/d'

ERE kullanan daha kısa bir sürüm, örneğin gnu sed ile:

sed -r '/^\s*$/d'

(Yok sed Not DEĞİL PCRE'yi destekler.)


3
@HuStmpHrrr gnu sed PCRE'yi hiç desteklemez. ile ERE olduğunu-r
Kent

8
OS X gerekli sed -i "" '/^[[:space:]]*$/d' <filename>,
jww

@BernieReiter ^\s*$tüm "boş" satırlarla eşleşir, burada boş anlamına gelir, satır karakter içermez veya satır yalnızca boş dizeler içerir (Örn. Boşluklar). Eşleşen tüm satırlar sed ile sed ile kaldırılır d.
Kent

97

awkÇözümü kaçırıyorum :

awk 'NF' file

Hangi dönecekti:

xxxxxx
yyyyyy
zzzzzz

Bu nasıl çalışıyor? Bu yana NF, bu hatlar boş olan "alanların sayısı" anlamına gelmektedir bu awk yanlış 0 değerlendirir ve bir hat basılır, böylece 0 fiedls sahiptir; ancak, en az bir alan varsa, değerlendirme Doğru'dur ve awkvarsayılan eylemini gerçekleştirir: geçerli satırı yazdırır.


1
Whoah. Hatta BSD awk "minimize" sürümü ile çalışıyor (sürüm 20121220 (FreeBSD). Teşekkürler :-)
Bernie Reiter

@BernieReiter bekliyoruz :) Evet, bu tüm awk sürümleri izin çok temel bir deyimsel şey.
fedorqui 'ÇOK zarar vermeyi durdur'

Ve çok daha hızlı olmasına rağmen - hızlı ve kirli bir test için - iki kez awk çağırıyorum: $ time (topic companies <data.tpx | awk 'NF' - | awk -f dialog_menu.awk -) real 0m0.006s user 0m0.000s sys 0m0.008s $ time (topic companies <data.tpx | gsed '/^\s*$/d' | awk -f dialog_menu.awk -) real 0m0.014s user 0m0.002s sys 0m0.006s Bunu örneğin bir desen gibi bir awk betiğine dahil etmenin şık bir yolunu biliyor musunuz? awk '/ mypattern / {do stuff ...}'
Bernie Reiter

@BernieReiter diyebilirsiniz awk 'NF {do stuff...}'.
fedorqui 'ÇOK zarar vermeyi durdur'

1
Bunun yalnızca boşluk içeren satırları yoksayacağını unutmayın.
wisbucky

60

sed '/^$/d'iyi olmalı, dosyayı yerinde değiştirmeyi mi bekliyorsunuz? Eğer öyleyse -ibayrağı kullanmalısınız .

Belki bu satırlar boş değildir, bu yüzden bu soruya bakın, bu soruya bakın txtfiles'dan boş satırları kaldırın, satırın başından ve satırından boşlukları kaldırmaya çalıştığınız şeyin bu olduğuna inanıyorum.


Evet. bir dosyayı değiştiriyorum. * .csv. sed komutuna -i nasıl yerleştirilmelidir?
jonas

2
sed -i '/^$/d'bunu yapmanın bir yoludur.
Alberto Zaccagni

49

1
Bunlar online aracında doğru görüntülenmeyen ancak []gerektiği değil burada kod için doğru değil bu yüzden, parantez ifadelerinde öncelenmelidir \[\[:space:\]\]veya \[ \t\]- olmalı [[:space:]]ve [ \t].
Benjamin W.

1
@BenjaminW. Yakaladığınız için teşekkürler. Bunlar orijinal yazardan değil, Düzen 3'ten normal metinden "kod" a değiştirildiğinde, daha sonra "\" çıkışını "ortaya çıkardı". Onları şimdi düzelttim.
wisbucky

30

Bunun en kolay ve en hızlı olduğuna inanıyorum:

cat file.txt | grep .

Tüm beyaz boşluk çizgilerini de göz ardı etmeniz gerekiyorsa, bunu deneyin:

cat file.txt | grep '\S'

Misal:

s="\
\
a\
 b\
\
Below is TAB:\
    \
Below is space:\
 \
c\
\
"; echo "$s" | grep . | wc -l; echo "$s" | grep '\S' | wc -l

çıktılar

7
5

5
Gerek yok cat, grepdosyaları da alır:grep . file.txt
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

3
Evet, biliyorum, ama ilk soru kaynağın bir dosya ya da başka bir şey olup olmadığından bahsetmedi. Çözümü hatların kaynağından ayırt etmek.
Vadim

2
grep '\S'kesinlikle taşınabilir değil. Varsa grep -Pkullanabilirsiniz, grep -P '\S'ancak tüm platformlarda desteklenmez.
Üçlü

grep .Diğer çözümlere kıyasla dezavantajı, tüm metni kırmızı olarak vurgulamasıdır. Diğer çözümler orijinal renkleri koruyabilir. Karşılaştırma unbuffer apt search foo | grep .içinunbuffer apt search foo | grep -v ^$
wisbucky

15

Kabul cevap yardımıyla burada ve yukarıdaki kabul cevap, ben kullandım:

$ sed 's/^ *//; s/ *$//; /^$/d; /^\s*$/d' file.txt > output.txt

`s/^ *//`  => left trim
`s/ *$//`  => right trim
`/^$/d`    => remove empty line
`/^\s*$/d` => delete lines which may contain white space

Bu, tüm üsleri kapsar ve ihtiyaçlarım için mükemmel çalışır. @Kent ve @kev orjinal posterleri için Kudos


5

Söyleyebilirsin:

sed -n '/ / p' filename    #there is a space between '//'

.. ki bu demek print all lines except the empty one(s)ve sessiz olmak
Timo

3

Başka bir seçenek olmadan sed, awk, perlvb

strings $file > $output

dizeler - dosyalarda yazdırılabilir karakter dizelerini yazdırır.


Bunun stringsyerine mi demek istiyorsun string?
Mickael B.

2

"Grep" kullanarak da böyle bir şey yapabilirsiniz:

egrep -v "^$" file.txt


2

Büyük olasılıkla metin dosyanız Windows'da oluşturulduğundan beklenmedik davranışı görüyorsunuz, bu nedenle satır sonu sırası \r\n. Sed2 komutunu çalıştırmadan veya kullanmadan önce dos2unix dosyasını UNIX stili bir metin dosyasına dönüştürmek için kullanabilirsiniz

sed -r "/^\r?$/d"

satır başı olsun veya olmasın boş satırları kaldırmak için.


Merhaba, -rbayrak ne yapıyor ve -idosyayı doğrudan değiştirmek ve ekrana yazdırmaktan kaçınmak mümkün. Buna ek olarak, bu komutun da işe yarayacağını düşünüyorumsed -r "/^\r$/d"
Alexander Cska

0

Özel bashcevabım, bunun perliçin global örüntü gbayrağıyla ikame operatörünün kullanılmasını tavsiye etmektir :

$ perl -pe s'/^\n|^[\ ]*\n//g' $file
xxxxxx
yyyyyy
zzzzzz

Bu cevap, boş satırların içinde boşluklar olup olmadığı ( [\ ]*) ve aynı zamanda |birden çok arama terimini / alanını ayırmak için kullanıldığını hesaplamayı gösterir . MacOS High Sierra ve CentOS 6/7 üzerinde test edildi.

FYI, OP'nin orijinal kodu macOS High Sierra ve CentOS 6/7 Linux üzerindeki Terminal'de yüksek performanslı bir süper bilgi işlem kümesinde sed '/^$/d' $filegayet iyi çalışıyor bash.


-3

Sed ile FreeBSD 10.1 ile benim için sadece bu çözümü çalıştı:

sed -e '/^[     ]*$/d' "testfile"

içinde []boşluk ve sekme sembolleri var.

test dosyası şunları içerir:

fffffff next 1 tabline ffffffffffff

ffffffff next 1 Space line ffffffffffff

ffffffff empty 1 lines ffffffffffff

============ EOF =============
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.