
Tengo un archivo con muchos números (solo números y cada número está en una línea). Quiero saber el número de líneas en las que el número es mayor que 100 (o cualquier otra cosa). ¿Cómo puedo hacer eso?
Respuesta1
Consideremos este archivo de prueba:
$ cat myfile
98
99
100
101
102
103
104
105
Ahora, contemos el número de líneas con un número mayor que 100:
$ awk '$1>100{c++} END{print c+0}' myfile
5
Cómo funciona
$1>100{c++}
Cada vez que el número en la línea es mayor que 100, la variable
c
se incrementa en 1.END{print c+0}
Una vez que hayamos terminado de leer el archivo,
c
se imprime la variable.Al agregar
0
ac
, forzamos a awk a tratarloc
como un número. Si hubiera líneas con números>100
, entoncesc
ya es un número. Si no lo hubiera, entoncesc
estaría vacío (consejo:irúvar). Al agregarle cero, cambiamos la cadena vacía a a0
, dando una salida más correcta.
Respuesta2
Solución similar conperl
$ seq 98 105 | perl -ne '$c++ if $_ > 100; END{print $c+0 ."\n"}'
5
Comparación de velocidad:números reportados durante 3 ejecuciones consecutivas
Archivo aleatorio:
$ 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
Conawk
$ time awk '$1>100{c++} END{print c+0}' rand_numbers.txt
14940305
real 0m7.754s
real 0m8.150s
real 0m7.439s
Conperl
$ time perl -ne '$c++ if $_ > 100; END{print $c+0 ."\n"}' rand_numbers.txt
14940305
real 0m4.145s
real 0m4.146s
real 0m4.196s
Y solo por diversión con grep
(Actualizado: más rápido que incluso Perl con 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
no es 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