Se as linhas em branco forem somente no final
grep -c '^$' myFile
ou:
grep -cx '' myFile
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?
Se as linhas em branco forem somente no final
grep -c '^$' myFile
ou:
grep -cx '' myFile
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. s/\n//
. wc -l
. 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 '
.
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 é? (-;
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 != ""
.
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
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
.
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
Tags grep text-processing wc