Conte o número de linhas em branco no final do arquivo

10

Eu tenho um arquivo com linhas em branco no final do arquivo. Posso usar grep para contar o número de linhas em branco no final do arquivo com o nome do arquivo sendo passado como variável no script?

    
por Raghunath Choudhary 30.11.2017 / 10:43

8 respostas

11

Se as linhas em branco forem somente no final

grep  -c '^$' myFile

ou:

grep -cx '' myFile
    
por 30.11.2017 / 11:17
11

Apenas por diversão, alguns spooky sed :

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

Explicação:

  • /./ endereça linhas com qualquer caractere, então /./! endereça linhas não vazias; para esses, o comando H os anexa ao espaço de espera. Assim, se para cada linha vazia adicionarmos uma linha ao espaço de espera, sempre haverá mais uma linha do que o número de linhas vazias. Nós vamos cuidar disso depois.
  • //h o padrão vazio corresponde à última expressão regular, que era qualquer caractere, portanto, qualquer linha não vazia é endereçada e movida para o espaço de espera pelo comando h para "redefinir" a coleta linhas para 1. Quando a próxima linha vazia for anexada, haverá duas novamente, como esperado.
  • $!d pára o script sem saída para cada linha exceto a última, portanto, comandos adicionais são executados somente após a última linha. Então, quaisquer linhas vazias que coletamos no espaço de espera estão no final do arquivo. Bom.
  • //d : O comando d é novamente executado apenas para linhas não vazias. Portanto, se a última linha não estiver vazia, sed sairá sem nenhuma saída. Zero linhas Bom.
  • x exchanges armazenam espaço e espaço padrão, portanto, as linhas coletadas estão no espaço padrão agora para serem processadas.
  • Mas lembramos que há uma linha demais, então a reduzimos removendo uma nova linha com s/\n// .
  • Voilà! O número de linhas corresponde ao número de linhas vazias no final (observe que a primeira linha não estará vazia, mas quem se importa), para que possamos contá-las com wc -l .
por 30.11.2017 / 12:39
8

Mais algumas opções de tac / tail -r do GNU:

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

Ou:

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

Observe que na saída de:

printf 'x\n '

Isto é, onde há um espaço extra após a última linha completa (que alguns poderiam considerar como uma linha extra em branco, mas pela definição POSIX de texto, não é um texto válido), aqueles dariam 0.

POSIXly:

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

mas isso significa ler o arquivo na íntegra ( tail -r / tac iria ler o arquivo para trás a partir do final em arquivos pesquisáveis). Isso dá 1 na saída de printf 'x\n ' .

    
por 30.11.2017 / 11:41
6

Como você está realmente pedindo por um grep solution eu adiciono este usando apenas o GNU grep (ok, também usando a sintaxe do shell e echo ...):

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

O que estou fazendo aqui? $(grep -c ".*" "$1") conta todas as linhas no arquivo, então nós subtraímos o arquivo sem as linhas vazias finais.

E como conseguir isso? $(grep -B42 . "$1" iria percorrer todas as linhas não vazias e 42 linhas antes delas, de forma que imprimisse tudo até a última linha não vazia, desde que não houvesse mais de 42 linhas vazias consecutivas antes de uma linha não vazia. Para evitar esse limite, considero $(grep -cv . "$1") como o parâmetro para a opção -B , que é o número total de linhas vazias, portanto, sempre grande o suficiente. Dessa forma, eu tirei as linhas vazias à direita e posso usar |grep -c ".*" para contar as linhas.

Brilhante, não é? (-;

    
por 30.11.2017 / 13:50
5

Outra solução awk . Essa variação redefine o contador k sempre que houver uma linha não vazia. Então, cada linha incrementa o contador. (Então, após a primeira linha de comprimento não em branco, k==0 .) No final, mostramos o número de linhas que contamos.

Prepare o arquivo de dados

cat <<'X' >input.txt
aaa

bbb
ccc



X

Conte as linhas em branco à direita na amostra

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

Nesta definição, uma linha em branco pode conter espaços ou outros caracteres em branco; ainda está em branco. Se você realmente quiser contar linhas vazias em vez de linhas em branco, altere NF para $0 != "" .

    
por 30.11.2017 / 11:59
2

to count the number of consecutive blank lines at the end of the file

Solução sólida awk + tac :

Amostra input.txt :

$ cat input.txt
aaa

bbb
ccc



$  # command line 

A ação:

awk '!NF{ if (NR==++c) { cnt++ } else exit }END{ print int(cnt) }' <(tac input.txt)
  • !NF - garante que a linha atual esteja vazia (não tem campos)
  • NR==++c - assegurando a ordem consecutiva de linhas em branco. ( NR - número de registro, ++c - contador auxiliar incrementado uniformemente)
  • cnt++ - contador de linhas em branco

A saída:

3
    
por 30.11.2017 / 11:05
1

IIUC, o seguinte script chamado count-blank-at-the-end.sh faria o trabalho:

#!/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"

Exemplo de uso:

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

Eu testei em GNU bash , Android mksh e em ksh .

    
por 30.11.2017 / 11:10
0

Solução alternativa Python :

Exemplo de entrada.txt:

$ cat input.txt
aaa

bbb
ccc



$  # command line 

A ação:

python -c 'import sys, itertools; f=open(sys.argv[1]);
lines=list(itertools.takewhile(str.isspace, f.readlines()[::-1]));
print(len(lines)); f.close()' input.txt

A saída:

3

link

    
por 30.11.2017 / 13:59