Je veux une commande bash dans laquelle je peux placer un pipe qui fera la somme d'une colonne de nombres. Je veux juste une commande rapide qui fasse quelque chose comme ceci :
cat FileWithColumnOfNumbers.txt | sum
Je veux une commande bash dans laquelle je peux placer un pipe qui fera la somme d'une colonne de nombres. Je veux juste une commande rapide qui fasse quelque chose comme ceci :
cat FileWithColumnOfNumbers.txt | sum
paste -sd+ infile | bc
<cmd> | paste -sd+ | bc
Éditer : Avec quelques pâte vous devez être plus explicite lorsque vous lisez les données de l'application stdin :
<cmd> | paste -sd+ - | bc
Options utilisées :
-s (serial) - fusionne toutes les lignes en une seule ligne
-d - utiliser un délimiteur autre que celui par défaut (le caractère
+
dans ce cas)
Juste pour info, le -s
est dans GNU paste
; il n'est pas pris en charge par Mac OS X 10.7.4 paste
. Toutefois, depuis la spécification POSIX 2008 de paste
soutient -s
Il s'agit d'un défaut de la version Mac OS X.
Pour info, pour OS X, j'ai dû ajouter un - à la fin de la commande coller pour que cela fonctionne sous OS X 10.6.8.
J'aime la réponse choisie. Cependant, il a tendance à être plus lent que awk puisque deux outils sont nécessaires pour faire le travail.
$ 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
Bon point ! Sous SunOS 5.8 bc, même le core dumps avec un fichier d'entrée aussi gros (voir mon post ci-dessous).
Awk est l'outil approprié pour ce travail ! La solution bc est correcte mais que se passe-t-il lorsque vous devez additionner deux colonnes ou peut-être filtrer les nombres négatifs. Avec awk, vous pouvez facilement et judicieusement ajouter une logique supplémentaire, avec la solution bc, vous finissez par passer par une autre commande (cut ou grep).
@radoulov. merci. je ne savais pas que le bc de Solaris avait des difficultés avec les grosses entrées.
Est-ce que deux lignes comptent ?
awk '{ sum += $1; }
END { print sum; }' "$@"
Vous pouvez alors l'utiliser sans le "cat" superflu :
sum < FileWithColumnOfNumbers.txt
sum FileWithColumnOfNumbers.txt
Pour info : sous MacOS X, vous pouvez le faire avec une ligne unique :
awk '{ sum += $1; } END { print sum; }' "$@"
@unhammer : Je n'ai pas accès à la 7ème édition d'UNIX et sa version de awk
plus. Je ne sais pas si la ligne unique aurait fonctionné là, mais je n'ai pas essayé à l'époque où j'ai appris awk
. Vous avez probablement raison ; toutes les versions actuelles de awk
sont susceptibles d'accepter la phrase unique.
[suite aux commentaires 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
+1 pour avoir signalé le coredump dans la version bc de ceci. J'hésite à changer la "réponse" de cette question car la version bc fonctionne bien pour moi (je totalise 30 numéros).
+1 pour la version Perl travaillant sur les nombres à virgule flottante. Aussi, pour exactement ce que je cherchais, voici la somme d'une colonne particulière (colonne 2 indexée à partir de zéro) : perl -nle '$s += (split)[2]; END { print $s }' foo.txt
ou en utilisant des tuyaux : cat foo.txt | perl -nle '$s += (split)[2]; END { print $s }'
.
Vous pouvez utiliser bc (calculatrice). En supposant que votre fichier avec des #s s'appelle "n" :
$ cat n
1
2
3
$ (cat n | tr "\012" "+" ; echo "0") | bc
6
Le site tr
transforme tous les retours à la ligne en "+" ; ensuite, nous ajoutons 0 après le dernier plus, puis nous faisons passer l'expression ( 1+2+3+0
) à la calculatrice
Ou, si vous êtes capable d'utiliser awk ou perl, voici un exemple en Perl :
$perl -nle '$sum += $_ } END { print $sum' n
6
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
En rapport : stackoverflow.com/q/3934423/376454
0 votes
Pour info, le
awk
La solution est à la fois plus facile à retenir et environ 2x plus rapide (voir aquí y aquí ).