Dosyanın sonundaki boş satır sayısını sayın


11

Dosyanın sonunda boş satırları olan bir dosya var. grepDosyanın sonunda komut dosyasında değişken olarak iletilen boş satır sayısını saymak için kullanabilir miyim ?


ardışık boş satır sayısını saymak için ?
RomanPerekhrest

2
@RomanPerekhrest Ben söyleyebilirim, aksi takdirde onlar "dosyanın sonunda" olmaz?
Sparhawk

'grep -cv -P' \ S 'dosyaadı' dosyadaki toplam boş satır sayısını sayar. Sondaki rakam sadece beynimi vergilendiriyor!
MichaelJohn

OP grep@MichaelJohn kitabımda saflık için kazandı istedi .
bu5hman

2
@ bu5hman Ama (itiraf ettiği gibi) soruyu cevaplamıyor. Gerçekten senin değil.
Sparhawk

Yanıtlar:


11

Boş satırlar yalnızca sonundaysa

grep  -c '^$' myFile

veya:

grep -cx '' myFile


grep -cv . myFile(kod golfçüler için) yazmanın başka bir yoludur. Ancak grepdosyanın herhangi bir yerinde boş satır varsa bir çözüm buldum .
Philippos

2
@Philippos, grep -cv .yalnızca geçerli karakterler oluşturmayan bayt içeren satırları da sayar.
Stéphane Chazelas

11

Sadece eğlence için, ürkütücü sed:

#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l

Açıklama:

  • /./herhangi bir karaktere sahip satırları adresler, böylece /./!boş olmayan satırları adresler; olanlar için, Hkomut tutun uzaya onları ekleyin. Bu nedenle, her boş satır için tutma alanına bir satır eklediysek, her zaman boş satır sayısından bir satır daha fazla olur. Daha sonra ilgileneceğiz.
  • //hboş desen, herhangi bir karakter olan son normal ifadeyle eşleşir, bu nedenle boş olmayan herhangi bir satır adreslenir ve toplanan satırları 1'e "sıfırlama" komutu ile bekleme alanına taşınırh . Bir sonraki boş satır ekleneceği zaman, beklendiği gibi yine iki tane olacak.
  • $!dkomut dosyasını son satır hariç her biri için çıktı olmadan durdurur, bu nedenle başka komutlar yalnızca son satırdan sonra yürütülür. Bekletme alanında topladığımız boş satırlar dosyanın sonundadır. İyi.
  • //d: dKomut yalnızca boş olmayan satırlar için tekrar yürütülür. Eğer son satır boş değilse, sedherhangi bir çıktı olmadan çıkacaktır. Sıfır çizgiler. İyi.
  • x borsalar boşluk ve desen alanı tutar, böylece toplanan çizgiler şimdi işlenecek desen alanındadır.
  • Ama bir satırın çok fazla olduğunu hatırlıyoruz, bu yüzden bir satırsonu kaldırarak azaltıyoruz s/\n//.
  • Voila Satır sayısı, sondaki boş satırların sayısıyla eşleşir (ilk satırın boş olmayacağını, ancak kimin umurunda olacağını unutmayın), böylece bunları sayabiliriz wc -l.

8

Biraz daha GNU tac/ tail -rseçenek:

tac file | awk 'NF{exit};END{print NR?NR-1:0}'

Veya:

tac file | sed -n '/[^[:blank:]]/q;p' | wc -l

Şunlara dikkat edin:

printf 'x\n '

Yani, son tam satırdan sonra fazladan bir boşluk varsa (bazıları ekstra boş satır olarak kabul edilebilir, ancak POSIX metnin tanımı ile geçerli metin değildir), bunlar 0 verir.

POSIXly:

awk 'NF{n=NR};END{print NR-n}' < file

ancak bu, dosyanın tam olarak okunması anlamına gelir ( tail -r/ tacdosyayı aranabilir dosyalarda sondan geriye doğru okur). Bu 1çıktı verir printf 'x\n '.


6

Aslında bir grepçözüm istediğin için bunu sadece GNU'ya dayanıyorum grep(tamam, ayrıca kabuk sözdizimi ve echo... kullanarak ):

#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))

Burada ne yapıyorum? $(grep -c ".*" "$1")dosyadaki tüm satırları sayar, ardından dosyayı boş satırlar olmadan özetleriz.

Ve bunları nasıl edinebilirim? $(grep -B42 . "$1"boş olmayan satırlardan ve 42 satırdan önce grep olur, bu nedenle boş olmayan bir satırdan önce arka arkaya 42'den fazla boş satır olmadığı sürece her şeyi son boş olmayan satıra kadar basar. Bu sınırı önlemek $(grep -cv . "$1")için -B, toplam boş satır sayısı olan seçenek için parametre olarak alıyorum , bu yüzden her zaman yeterince büyük. Bu şekilde boş satırları çıkardım |grep -c ".*"ve satırları saymak için kullanabilirim .

Harika, değil mi? (-;


+1 çünkü bu korkunç bir kod olmasına rağmen, teknik olarak soruyu olduğu gibi cevaplıyor ve sizi işaretlemek için dayanamıyorum ;-)
roaima

Grepmeister. Biz layık değiliz.
bu5hman

Sapıklık için +1. Başka bir (muhtemelen daha hızlı?) Seçenek tac | grepilk boş olmayan -m -A 42, daha sonra eksi bir olana olacaktır. Hangisinin daha verimli olduğundan emin değilim, ama wc -l | cut -d' ' -f1boş satırları selamlamak yerine?
Sparhawk

Evet, tabi, birlikte bir çok şey yapabilir tac, wcve cut, ama burada kendimi kısıtlamak için çalıştı grep. Buna sapıklık diyebilirsiniz, buna spor diyorum. (-;
Philippos

5

Başka bir awkçözüm. Bu varyasyon k, boş olmayan her satır olduğunda sayacı sıfırlar . Ardından, her satır sayacı artırır. (Yani, boş olmayan ilk uzunluk çizgisinden sonra k==0.) Sonunda saydığımız satır sayısını çıkarırız.

Veri dosyasını hazırlayın

cat <<'X' >input.txt
aaa

bbb
ccc



X

Örnekteki boş satırları sayma

awk 'NF {k=-1}; {k++}; END {print k+0}' input.txt
3

Bu tanımda, boş bir satır boşluklar veya başka boş karakterler içerebilir; hala boş. Eğer gerçekten boş satırları yerine boş satırlar, değişiklik saymak istiyorsanız NFiçin $0 != "".


Neden $0 > ""? Bu, birçok uygulamada kullanılandan strcoll()daha az verimli $0 != ""olan kullanımlar kullanır memcmp()(POSIX, bunun kullanılmasını gerektirir strcoll()).
Stéphane Chazelas

@ StéphaneChazelas Bunun $0 > ""farklı olabileceğini düşünmedim $0 != "". awkYine de "yavaş" bir operatör gibi davranmaya eğilimliyim (giriş olarak büyük bir veri setim olduğunu ve işlemin zaman açısından kritik olduğunu bilirsem, miktarı azaltmak için neler yapabileceğimi göreceğim awk- I bu grep | awkgibi durumlarda yapıları kullanmıştır ). Ancak, ne varsayalım hızlı bir göz vardı POSIX tanımı ya herhangi bir referans göremiyorum strcoll()ya memcmp(). Neyi kaçırıyorum?
roaima

strcoll()== dizeler, yerel ayara özgü harmanlama sırası kullanılarak karşılaştırılacaktır . Önceki sürümle karşılaştırın . Onu ben yetiştirdim. Ayrıca bkz. Austingroupbugs.net/view.php?id=963
Stéphane Chazelas

@ StéphaneChazelas a <= b && a >= b, mutlaka aynı olmadığı bir uygulama a == b. Ah!
roaima

Yani GNU durum awkveya bash(onun için [[ a < b ]]için örneğin GNU sistemlerinde en_US.UTF-8 yerellerde operatörler) vs örneğin (için bashhiçbiri, <, >, =olanlar için gerçek dönmek). Tartışmalı bir şekilde bu yerlerin tanımında bash /
awk'den

2

dosyanın sonundaki ardışık boş satır sayısını saymak için

Katı awk+ tacçözelti:

Örnek input.txt:

$ cat input.txt
aaa

bbb
ccc



$  # command line 

Eylem:

awk '!NF{ if (NR==++c) { cnt++ } else exit }END{ print int(cnt) }' <(tac input.txt)
  • !NF- geçerli satırın boş olmasını sağlar (alan içermez)
  • NR==++c- boş satırların art arda sıralanmasını sağlamak. ( NR- kayıt numarası, ++c- eşit olarak artırılmış yardımcı sayaç)
  • cnt++- boş satır sayacı

Çıktı:

3

1

IIUC, şu komut dosyası denir count-blank-at-the-end.sh:

#!/usr/bin/env sh

count=$(tail -n +"$(grep . "$1" -n | tail -n 1 | cut -d: -f1)" "$1" | wc -l)
num_of_blank_lines=$((count - 1))

printf "%s\n" "$num_of_blank_lines"

Örnek kullanım:

$ ./count-blank-at-the-end.sh FILE
4

Bunu test GNU bash, Android mkshve de ksh.


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.