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

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

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

Responder1

Se as linhas em branco foremapenasno final

grep  -c '^$' myFile

ou:

grep -cx '' myFile

Responder2

Apenas por diversão, alguns assustadores sed:

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

Explicação:

  • /./endereça linhas com qualquer caractere, portanto /./!endereça linhas vazias (como /^$/, mas quero reutilizar o padrão oposto); para esses, o Hcomando os anexa ao espaço de espera. Assim, se para cada linha vazia adicionamos uma linha ao espaço de espera, sempre haverá uma linha a mais que o número de linhas vazias. Cuidaremos disso mais tarde.
  • //ho padrão vazio corresponde à última expressão regular, que era qualquer caractere, portanto, qualquer linha não vazia é endereçada emudou-separa o espaço de espera pelo hcomando para "redefinir" as linhas coletadas para 1. Quando a próxima linha vazia for anexada, haverá duas novamente, como esperado.
  • $!dinterrompe o script sem saída para cada linha, exceto a última linha, portanto, comandos adicionais são executados somente após a última linha. Portanto, quaisquer linhas vazias que coletamos no espaço de espera estão no final do arquivo. Bom.
  • //d: O dcomando é novamente executado apenas para linhas não vazias. Portanto, se a última linha não estiver vazia, sedsairá sem nenhuma saída. Zero linhas. Bom.
  • xas trocas retêm espaço e espaço padrão, portanto, as linhas coletadas estão agora no espaço padrão para serem processadas.
  • Mas lembramos que há uma linha a mais, 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), então podemos contá-las com wc -l.

Responder3

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

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 '

Ou seja, onde houver 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), isso daria 0.

POSIXamente:

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

mas isso significa ler o arquivo por completo ( tail -r/ tacleria o arquivo de trás para frente nos arquivos pesquisáveis). Isso dá 1na saída de printf 'x\n '.

Responder4

Como você está realmente pedindo umgrepsoluçãoEu adiciono este contando apenas com GNU grep(ok, também usando sintaxe 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 do arquivo e subtraímos o arquivo sem as linhas vazias finais.

E como conseguir isso? $(grep -B42 . "$1"iria grep todas as linhas não vazias e 42 linhas antes delas, então imprimiria 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, tomo $(grep -cv . "$1")como parâmetro da -Bopção, que é o número total de linhas vazias, portanto sempre grande o suficiente. Dessa forma, eliminei as linhas vazias finais e posso usá-las |grep -c ".*"para contar as linhas.

Brilhante, não é? (-;

informação relacionada