
Eu tenho um arquivo com muitos números (apenas números e cada número está em uma linha). Quero descobrir o número de linhas em que o número é maior que 100 (ou qualquer outra coisa). Como eu posso fazer isso?
Responder1
Vamos considerar este arquivo de teste:
$ cat myfile
98
99
100
101
102
103
104
105
Agora, vamos contar o número de linhas com número maior que 100:
$ awk '$1>100{c++} END{print c+0}' myfile
5
Como funciona
$1>100{c++}
Cada vez que o número na linha é maior que 100, a variável
c
é incrementada em 1.END{print c+0}
Após terminarmos de ler o arquivo, a variável
c
é impressa.Ao adicionar
0
,c
forçamos o awk a ser tratadoc
como um número. Se houvesse alguma linha com números>100
, entãoc
já é um número. Se não houvesse, entãoc
estaria vazio (gorjeta:iruvar). Ao adicionar zero a ele, alteramos a string vazia para a0
, fornecendo uma saída mais correta.
Responder2
Solução semelhante comperl
$ seq 98 105 | perl -ne '$c++ if $_ > 100; END{print $c+0 ."\n"}'
5
Comparação de velocidade:números relatados por 3 execuções consecutivas
Arquivo aleatório:
$ perl -le 'print int(rand(200)) foreach (0..10000000)' > rand_numbers.txt
$ perl -le 'print int(rand(100200)) foreach (0..10000000)' >> rand_numbers.txt
$ shuf rand_numbers.txt -o rand_numbers.txt
$ tail -5 rand_numbers.txt
114
100
66125
84281
144
$ wc rand_numbers.txt
20000002 20000002 93413515 rand_numbers.txt
$ du -h rand_numbers.txt
90M rand_numbers.txt
Comawk
$ time awk '$1>100{c++} END{print c+0}' rand_numbers.txt
14940305
real 0m7.754s
real 0m8.150s
real 0m7.439s
Comperl
$ time perl -ne '$c++ if $_ > 100; END{print $c+0 ."\n"}' rand_numbers.txt
14940305
real 0m4.145s
real 0m4.146s
real 0m4.196s
E só por diversão com grep
(Atualizada: mais rápido que Perl com LC_ALL=C)
$ time grep -xcE '10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}' rand_numbers.txt
14940305
real 0m10.622s
$ time LC_ALL=C grep -xcE '10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}' rand_numbers.txt
14940305
real 0m0.886s
real 0m0.889s
real 0m0.892s
sed
não é divertido:
$ time sed -nE '/^10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}$/p' rand_numbers.txt | wc -l
14940305
real 0m11.929s
$ time LC_ALL=C sed -nE '/^10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}$/p' rand_numbers.txt | wc -l
14940305
real 0m6.238s