Comando Bash para sumar una columna de números [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Quiero un comando bash que pueda canalizar en el que se sumará una columna de números. Solo quiero un trazador de líneas rápido que haga algo esencialmente como esto:

cat FileWithColumnOfNumbers.txt | sum
 281
Author: Jonathan Leffler, 2010-06-22

10 answers

Usando el archivo existente:

paste -sd+ infile | bc

Usando stdin:

<cmd> | paste -sd+ | bc

Editar: Con algunas implementaciones de paste debe ser más explícito al leer desde stdin :

<cmd> | paste -sd+ - | bc

 638
Author: Dimitre Radoulov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-09 18:14:21

Me gusta la respuesta elegida. Sin embargo, tiende a ser más lento que awk ya que se necesitan 2 herramientas para hacer el trabajo.

$ wc -l file
49999998 file

$ time paste -sd+ file | bc
1448700364

real    1m36.960s
user    1m24.515s
sys     0m1.772s

$ time awk '{s+=$1}END{print s}' file
1448700364

real    0m45.476s
user    0m40.756s
sys     0m0.287s
 140
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-23 00:15:12

¿Cuentan dos líneas?

awk '{ sum += $1; }
     END { print sum; }' "$@"

Entonces puedes usarlo sin el superfluo 'gato':

sum < FileWithColumnOfNumbers.txt
sum   FileWithColumnOfNumbers.txt

FWIW: en macOS X, puede hacerlo con un solo trazador de líneas:

awk '{ sum += $1; } END { print sum; }' "$@"
 40
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-22 19:02:10

El siguiente comando agregará todas las líneas (primer campo de la salida awk)

awk '{s+=$1} END {print s}' filename
 29
Author: minhas23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-18 05:21:44

[un seguimiento de los comentarios de ghostdog74]

bash-2.03$ uname -sr
SunOS 5.8

bash-2.03$ perl -le 'print for 1..49999998' > infile

bash-2.03$ wc -l infile
 49999998 infile

bash-2.03$  time paste -sd+ infile | bc
bundling space exceeded on line 1, teletype
Broken Pipe

real    0m0.062s
user    0m0.010s
sys     0m0.010s

bash-2.03$ time nawk '{s+=$1}END{print s}' infile
1249999925000001

real    2m0.042s
user    1m59.220s
sys     0m0.590s
bash-2.03$ time /usr/xpg4/bin/awk '{s+=$1}END{print s}' infile
1249999925000001

real    2m27.260s
user    2m26.230s
sys     0m0.660s

bash-2.03$ time perl -nle'
  $s += $_; END { print $s }
   ' infile
1.249999925e+15

real    1m34.663s
user    1m33.710s
sys     0m0.650s
 15
Author: Dimitre Radoulov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-23 08:20:45

Puede usar bc (calculadora). Suponiendo que su archivo con # s se llama"n":

$ cat n
1
2
3
$ (cat n | tr "\012" "+" ; echo "0") | bc 
6

El tr cambia todas las líneas nuevas a "+"; luego agregamos 0 después del último más, luego canalizamos la expresión (1+2+3+0) a la calculadora

O, si está de acuerdo con el uso de awk o perl, aquí hay un Perl one-liner:

$perl -nle '$sum += $_ } END { print $sum' n
6
 10
Author: DVK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-22 19:10:47
while read -r num; do ((sum += num)); done < inputfile; echo $sum
 6
Author: Dennis Williamson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-22 19:56:09

Use un bucle for para iterar sobre su archivo {

sum=0; for x in `cat <your-file>`; do let sum+=x; done; echo $sum
 4
Author: t6d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-22 20:20:28

Si tienes ruby instalado

cat FileWithColumnOfNumbers.txt | xargs ruby -e "puts ARGV.map(&:to_i).inject(&:+)"
 4
Author: Joe Cannatti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-10 14:53:52
[root@pentest3r ~]# (find / -xdev -size +1024M) | (while read a ; do aa=$(du -sh $a | cut -d "." -f1 ); o=$(( $o+$aa )); done; echo "$o";)
 -4
Author: paco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-20 05:12:44