5. satırdan başlayarak boş satırlar nasıl silinir


10

Bu bende var:

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

hangi boş çizgiler sıyırma ve iyi çalışıyor. Bunu sadece 5-999 satırları (veya ideal olarak 5'ten dosya sonuna) için nasıl yapabilirim.

Denedim:

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

ama ikisi de işe yaramadı (hata yok).


Sadece emin olmak için: Boş veya boş olup olmadıklarına bakılmaksızın 1-4 arasındaki satırları tutmak mı yoksa boş veya boş olup olmadıklarına bakılmaksızın 1-4. Satırları silmek istiyor musunuz? (Şimdiye kadar ilkini varsaydım, ancak denediğiniz ikinci komut beni meraklandırıyor.)
Uwe

Yanıtlar:


12

5. satırdan başlayarak tüm boş satırları silmek ve 1'den 4'e kadar satırları saklamak istiyorsanız,

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

{İlk komut nedenle, gruplama operatörü 5,${vasıtası "giriş sonuna kadar hat 5 den ( $) eşleme kadar aşağıdaki komutları }". Arasındaki {ve }adreslerinin başına önek eklenebilir, bu nedenle iç komut /^$/d" satırın başı ( ^) ile bitişi ( $) arasında hiçbir şey yoksa , silin" anlamına gelir. Sed komutları ile ayrılabilir ;. (Bu, sed'in kötü belgelenmiş bir özelliğidir. Çoğu sed uygulaması tarafından desteklenir, ancak tamamen taşınabilir değildir .) Hauke ​​tarafından belirtildiği gibi, ;after {isteğe bağlıdır; yine de bir tane }gerekli.

5. satırdan başlayarak tüm boş satırları silmek ve ayrıca 1-4. Satırları silmek istiyorsanız, daha kolaydır:

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

Güzel. Adreslerin bu şekilde yuvalanabileceğini bilmiyordum. Benim için de öncü olmadan çalışıyor ;.
Hauke ​​Laging

Evet, ilkinde haklısın ;.
Uwe

@Hauke ​​Laging Bir sed komut dosyasındaki komutları ';' ile ayırabilirsiniz. bunun yerine onları ayrı satırlara koymak. Bu "belgelenmemiş" bir özelliktir.
Predrag Punosevac

4

Awk kullanan başka bir seçenek:

awk 'NR<5||/./'

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

Düzenleme 1:

Bunu açıklamam gerekiyor, bu yüzden ...

Bu gereksiz bir şekilde karmaşık. Adres aralıklarına izin verildiğini bilmiyordum {}. Bu yüzden "boş satırları sil" i farklı şekilde ifade etmek zorunda kaldım. Çekirdek komut tsed'in yoludur if ... then. Tdaha kolay olurdu, ancak yalnızca GNU sed için kullanılabilir. Adam sayfasına atıfta bulunuyorum:

t label: as ///, son giriş satırı okunduğundan ve son t veya T komutundan bu yana başarılı bir değişiklik yaptıysa, etiketlemek için dallayın; etiket atlanırsa, komut dosyasının sonuna dallanır.

Ünlü semri kötüye kullanıyorum . Hiçbir şeyin yerini almaz, sadece hattın boş olup olmadığını test eder. Böylece boş bir satırı boş bir satırla değiştirir (her halükarda silindiğinden herhangi bir şeyi yedek olarak kullanabilir).

Eğer sbir "değiştirme" yapmışsa, çizgi boştur. Bu durumda komut dyürütülür. Aksi takdirde hiçbir şey yapılmaz. tBir seylem durumunda atlama değil gibi ben komut bdosyasının sonuna atlamak için şube komut gerekir . : labelşube hedefleridir. Gibi gotoo zamanlar karanlık çağlarda (... te-hee icat edildi sed olduğunda).

Başka bir seçenek de s, boş olmayan tüm satırları "değiştirmek", sdaha karmaşık ama komutun geri kalanını kolaylaştırmak olacaktır:

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

^..*$"boş olmayan satır" ve \1"ilk köşeli parantezlerin içeriği" anlamına gelir.


OP uğruna biraz açıklama (beyninin bunu okuyan kulaklardan sürünmeye çalıştığını hissedebiliyorum ...)
vonbrand
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.