[shell] Utilitaire calculant des sommes ?

Utilitaire calculant des sommes ? [shell] - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 23-05-2007 à 20:33:30    

Bonsoir à tous,
 
Je cherche un utilitaire pour calculer rapidement une somme, sans passer par un script shell, qui marcherait comme ça :
 

Code :
  1. [user@localhost]$ cat liste_nombres|sum


 
En supposant donc que j'ai un nombre par ligne dans liste_nombres.
 
Ca existe déjà ou je fais un script ?
 
Merci d'avance

Reply

Marsh Posté le 23-05-2007 à 20:33:30   

Reply

Marsh Posté le 23-05-2007 à 20:42:51    

pas testé mais ça a l'air pas mal

Citation :


 apt-cache show num-utils
Package: num-utils
Priority: optional
Section: math
Installed-Size: 200
Maintainer: Bart Martens <bartm@knars.be>
Architecture: all
Version: 0.5-7
Depends: perl
Filename: pool/main/n/num-utils/num-utils_0.5-7_all.deb
Size: 54860
MD5sum: 889fe79f801b7c866efac6d96e52ce4e
SHA1: 7f1c0527a08a7a7768732d67311a9ddd1e3fdad8
SHA256: 7f4b31c4dea1d6970c1f1967222cc1c578fbe0b3d61f10e170d170ed3e3baf32
Description: programs for dealing with numbers from the command line
 The 'num-utils' are a set of programs for dealing with numbers from the
 Unix command line. Much like the other Unix command line utilities like
 grep, awk, sort, cut, etc. these utilities work on data from both
 standard in and data from files.
 .
 Includes these programs:
  * numaverage: A program for calculating the average of numbers.
  * numbound: Finds the boundary numbers (min and max) of input.
  * numinterval: Shows the numeric intervals between each number in a sequence.
  * numnormalize: Normalizes a set of numbers between 0 and 1 by default.
  * numgrep: Like normal grep, but for sets of numbers.
  * numprocess: Do mathematical operations on numbers.
 * numsum: Add up all the numbers.
  * numrandom: Generate a random number from a given expression.
  * numrange: Generate a set of numbers in a range expression.
  * numround: Round each number according to its value.
 .
  Homepage: http://suso.suso.org/programs/num-utils/
Tag: implemented-in::perl, interface::commandline, role::program, scope::utility



Message édité par 911GT3 le 23-05-2007 à 20:43:12
Reply

Marsh Posté le 23-05-2007 à 20:46:54    

[jorge@blackknight]-(~)> cat numbers.txt  
5
15
25
42
[jorge@blackknight]-(~)> numsum -c -r numbers.txt
87


Message édité par 911GT3 le 23-05-2007 à 20:48:48
Reply

Marsh Posté le 23-05-2007 à 20:53:12    

d'un autre côté, c'est du perl :D
 

cat /usr/bin/numsum  
#!/usr/bin/perl -w
 
# numsum:  This program adds up all numbers it encounters and prints out
#          the total at the end on STDOUT.  
#    
# Copyright (C) 2002-2004 Suso Banderas
 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# You may contact the author at <suso@suso.org>.
 
#######################
# VARIABLES AND SETUP #
#######################
 
use Getopt::Std;
#use strict;
use vars qw/ %opts /;
 
my ($file, $finalsum, @number_array, @columns_to_print, @column_output, $output_line, $string_seperator, $verbose);
 
getopts('123456789cdhiIqrs:Vx:y:', \%opts);
 
 
if ($opts{'h'}) {
    &help;
    exit(0);
}
 
if ($opts{'d'}) {
    $verbose = 3;
    print STDERR "Debug mode\n";
} elsif ($opts{'V'}) {
    $verbose = 2;
    print STDERR "Verbose mode\n";
} elsif($opts{'q'}) {
    $verbose = 0;  # No output except the final answer.
} else {
    $verbose = 1;  # Normal output.
}
 
# I'm not sure whether this should stay in or not.  It's mainly just for convience.
# It's a bad hack because you can only specify 1 through 9.  Maybe sometime I'll figure
# out how to bypass getopts to specify extra options.
for ($n = 1 ; $n < 10; $n++) {
    if ($opts{$n}) {
        $opts{'c'} = 1;
        $opts{'x'} = $n;
    }
}
 
if ($opts{'x'}) {
    @columns_to_print = split(/,/, $opts{'x'});
}
 
if ($opts{'y'}) {
    @rows_to_print = split(/,/, $opts{'y'});
}
 
if ($opts{'s'}) {
    $string_seperator = $opts{'s'};
} else {
    $string_seperator = "\\s+";
}
 
 
################
# MAIN PROGRAM #
################
 
if (@ARGV) {
    foreach $file (@ARGV) {
        print STDERR "Reading from file $file.\n" if ($verbose >= 2);
        open (ARGFILE, "$file" ) && process_filehandle(\*ARGFILE, \@number_array)
        || $verbose && warn "Couldn't open file $file for reading: $!\n";
        close(ARGFILE);
    }
} else {
    print STDERR "Reading from STDIN.\n" if ($verbose >= 2);
    process_filehandle(\*STDIN, \@number_array);
}
 
my $number_array_length = @number_array;
 
if ($opts{'c'}) { # Handle column sum output.
   
    my @column_output = ();
    my $i;
    for ($i = 0; $i < $number_array_length; $i++) {
        my @add_this_array = split(/$string_seperator/, $number_array[$i]);
        sum_columns(\@column_output, \@add_this_array);
    }
 
    # Now print out the columular output.
    if ($opts{'x'}) {
        my @final_output = ();
        foreach $column_number (@columns_to_print) {
            push (@final_output, $column_output[$column_number-1]);
        }
        $output_line = join(" ", @final_output);
    } else {
        $output_line = join(" ", @column_output);
    }
 
    print "$output_line\n";
 
} elsif ($opts{'r'}) { # Handle row sum output.
 
    my $i;
    if ($opts{'y'}) {
        foreach $row_number (@rows_to_print) {
            my @add_this_array = split(/ /, $number_array[$row_number-1]);
            my $row_sum = 0;
            foreach $row_value (@add_this_array) {
                $row_sum = decimals_friendly_sum( $row_sum, $row_value );
            }
            print "$row_sum\n";
        }
    } else {
        for ($i = 0; $i < $number_array_length; $i++) {
            my @add_this_array = split(/ /, $number_array[$i]);
            my $row_sum = 0;
            foreach $row_value (@add_this_array) {
                next if ($row_value !~ m/^\-?[0-9]*\.?[0-9]+$/);
                $row_sum = decimals_friendly_sum( $row_sum, $row_value );
            }
            print "$row_sum\n";
        }
    }
 
} else {
    $finalsum = add_array(\@number_array);
 
    if ($opts{'i'}) {
        $finalsum = int($finalsum);
    } elsif ($opts{'I'}) {
        if ($finalsum == int($finalsum)) {
            $finalsum = 0;
        } else {
            $finalsum =~ s/^(\-?)[0-9]*\.([0-9]*)$/$1.$2/;
        }
    }
 
    print "$finalsum\n";
}
 
exit(0);
 
 
###############
# SUBROUTINES #
###############
 
sub help {
        print <<"EOF";
---------------------------------------------------------------------------
numsum :  A program that adds up all numbers of input and returns the sum.
---------------------------------------------------------------------------
Usage:
        numsum [options] <file>   (Input from a file.)
        | numsum [options]        (Input from command pipeline.)
        numsum [options]          (Input on STDIN.  Use Ctrl-D to stop.)
 
Options:
        -i      Only return the integer portion of the final sum.
        -I      Only return the decimal portion of the final sum
 
        -c      Print out the sum of each column.
        -r      Print out the sum of each row.
 
        -x <n>  Specify a comma seperated list of columns to print.
        -y <n>  Specify a comma seperated list of rows to print.
 
        -s <string> Specify a seperator string for spliting columns.
                    This defaults to consecutive whitespace.
 
        -d      Debug. For developers only.
        -h      Help: You're looking at it.
        -V      Increase verbosity.
        -q      Quiet mode, don't print any warnings.
EOF
}
 
sub decimals_friendly_sum
{
        # try summing 1.99 and -1.90 to understand why
        my $number_a = shift;
        my $number_b = shift;
        my $dec_a = ( $number_a =~ /\.([^\.]*)$/ ? length($1) : 0 );
        my $dec_b = ( $number_b =~ /\.([^\.]*)$/ ? length($1) : 0 );
        my $factor = 10 ** ( $dec_a > $dec_b ? $dec_a : $dec_b );
        $number_a *= $factor;
        $number_b *= $factor;
        return ( $number_a + $number_b ) / $factor;
}
 
# This function is used so that we can genericize what filehandle
# we are getting our information from.
sub process_filehandle {
    my $filehandle = shift;
    my $number_array_ref = shift;
 
    while (<$filehandle> ) {
        my $line = $_;
        chomp($line);
        if ($opts{'c'} || $opts{'r'}) {   # Process columns or rows
 
            # Make each line column friendly by changing all non-numeric words into 0.
 
 
            # Some ideas from the #perl channel on irc.freenode.org.  Thanks to v, dkr, Khisanth and dudeman
 
            #$input = join ' ', map { /\D/ ? 0 : $_ } split / +/, $input;
            #s!(\S+)!$1=~/\D/?0:$1!ge;
           
            # This one works best.  
            $line =~ s!(\S+)!$1=~/^(\-?[0-9]*\.?[0-9]+)$/?$1:0!ge;
 
            push(@$number_array_ref, $line);
 
        } else {   # Normal processing.
            if ($line =~ /^\s*(\-?[0-9]*\.?[0-9]+)/) {
                print STDERR "number: $1\n" if ($verbose >= 3);
                push(@$number_array_ref, $1);
            }
        }
    }
    return 1;
}
 
 
# Function for adding up numbers
sub add_array {
    my $arrayref = shift;
    my $runningtotal = 0;
    my $number;
 
    foreach $number (@$arrayref) {
        print STDERR "$number\n" if ($verbose >= 2);
        $runningtotal = decimals_friendly_sum( $runningtotal, $number );
    }
    return $runningtotal;
}
 
# Function for summing up the columns.
sub sum_columns {
    my $sum_array_ref = shift;
    my $input_array_ref = shift;
 
 
    my $input_array_length = @$input_array_ref;
    my $x;
    for ($x = 0; $x < $input_array_length; $x++) {
        if (${$sum_array_ref}[$x]) {
            ${$sum_array_ref}[$x] = decimals_friendly_sum( ${$sum_array_ref}[$x], ${$input_array_ref}[$x] );
        } else {
            ${$sum_array_ref}[$x] = ${$input_array_ref}[$x];
        }
    }
    return 1;
}
 
# Lay down some of that perl pod action.
=pod
 
=head1 NAME
 
numsum - numsum program file
 
=head1 SYNOPSIS
 
B<numsum> [-iIcdhrsvxy] <FILE>
 
| B<numsum> [-iIcdhrsvxy]   (Input on STDIN from pipeline.)
 
B<numsum> [-iIcdhrsvxy]     (Input on STDIN.  Use Ctrl-D to stop.)
 
 
=head1 DESCRIPTION
 
B<numsum>
will take all the numbers on stdin and return the sum of those numbers.  Currently
it only processes the first number on each line.  Besides positive numbers, it also
handles negative numbers and numbers with decimals.
 
=head1 OPTIONS
 
    -i  Only return the integer portion of the final sum.
    -I  Only return the decimal portion of the final sum.
 
    -c      Print out the sum of each column.
    -r      Print out the sum of each row.
 
    -x <n>  Specify a comma seperated list of columns to print.
    -y <n>  Specify a comma seperated list of rows to print.
 
    -s <string> Specify a string to use as a seperator for columns.
                This defaults to be consecutive whitespace (\s+).
 
    -h  Help: You're looking at it.
    -V  Increase verbosity.
    -d  Debug mode.  For developers
    -q  Quiet mode, don't print any warnings.
 
=head1 EXAMPLES
 
Simply add up the numbers in a file.
    $ numsum numbers.txt
    4315
 
Enter your own numbers on STDIN. The last number is the answer.
    $ numsum
    4
    21
    98
    100
    223
 
Use it in a command pipeline.
    $ ls -1s | grep .mp3 | numsum -c -x 5
    72288
 
Add up the total byte count in a http log file.
    $ cat access_log | awk {'print $10'} numsum
 
    or  
 
    numsum -c -x 10 access_log
 
Add up the columns of numbers of a file.
 
    $ cat columns
    1 6 11 16 21
    2 7 12 17 22
    3 8 13 18 23
    4 9 14 19 24
    5 10 15 20 25
    $ numsum -c columns
    15 40 65 90 115
 
Add up the 1st, 2nd and 5th columns only.
 
    $ numsum -c -x 1,2,5 columns
    15 40 115    
 
Add up the rows of numbers of a file.
 
     $ numsum -r columns
     55
     60
     65
     70
     75
 
Add up the 2nd and 4th rows.
 
     $ numsum -r -y 2,4 columns
     60
     70
 
=head1 SEE ALSO
 
numaverage(1), numbound(1), numinterval(1), numnormalize(1), numgrep(1), numprocess(1), numrandom(1), numrange(1), numround(1)
 
=head1 COPYRIGHT
 
numsum is part of the num-utils package, which is copyrighted by
Suso Banderas and released under the GPL license.  Please read
the COPYING and LICENSE files that came with the num-utils package
 
  Developers can read the GOALS file and contact me about providing
submitions or help for the project.
 
=head1 MORE INFO
 
More info on numsum can be found at:
 
=over 1
 
=item B<http://suso.suso.org/programs/num-utils/>
 
=back
 
=cut
 

Reply

Marsh Posté le 23-05-2007 à 21:00:47    


[nico@angband:~] echo $((2 + 3 +4))
9


 
:o


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 23-05-2007 à 21:38:58    

Alt + F2 le fait.


---------------
Décentralisons Internet-Bépo-Troll Bingo - "Pour adoucir le mélange, pressez trois quartiers d’orange !"
Reply

Marsh Posté le 23-05-2007 à 22:37:34    

Fork Bomb a écrit :

Alt + F2 le fait.


c'est pas trop intégré au shell  [:pingouino]


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 23-05-2007 à 22:40:09    

Fork Bomb a écrit :

Alt + F2 le fait.


[:pingouino dei]


---------------
Be the one with the flames.
Reply

Marsh Posté le 23-05-2007 à 22:41:58    


surement une fitioure d'un WM quelconque :o


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 23-05-2007 à 22:46:05    

Ah. Foutus jeunes avec de interfaces évoluées  [:kiki]


---------------
Be the one with the flames.
Reply

Marsh Posté le 23-05-2007 à 22:46:05   

Reply

Marsh Posté le 23-05-2007 à 22:47:13    

est ce qu'on fait les cakes avec nos ttys nous hein ?


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 23-05-2007 à 23:08:15    

black_lord a écrit :

c'est pas trop intégré au shell  [:pingouino]


Relis bien le 1er post: il veut pas d'un truc en shell.


---------------
Décentralisons Internet-Bépo-Troll Bingo - "Pour adoucir le mélange, pressez trois quartiers d’orange !"
Reply

Marsh Posté le 23-05-2007 à 23:16:35    

il ne veut pas d'un utilitaire, le moins il en installe, le mieux c'est :o


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 23-05-2007 à 23:23:32    

Bah, pour l'instant j'ai fait une bête boucle for avec du expr dedans. Je chercherai mieux quand j'aurai un peu plus de temps.
 
Merci en tout cas pour les réponses.

Reply

Marsh Posté le 23-05-2007 à 23:25:10    

Ipso a écrit :

Bah, pour l'instant j'ai fait une bête boucle for avec du expr dedans. Je chercherai mieux quand j'aurai un peu plus de temps.

 

Merci en tout cas pour les réponses.

 

qu'est-ce que tu recherches de plus :??:
un binaire statique :??:


Message édité par 911GT3 le 23-05-2007 à 23:25:24
Reply

Marsh Posté le 24-05-2007 à 10:14:09    

Et pourquoi pas dc?
cat sum
1
2+
3+
p
 
et faire cat sum|dc
 
 

Reply

Marsh Posté le 24-05-2007 à 10:21:12    

black_lord a écrit :


[nico@angband:~] echo $((2 + 3 +4))
9


 
:o


[wedge@chimaera ~]$ echo $[2+3+4]
9


 
:o


---------------
Wedge#2487 @HS -#- PW: +∞ -#- Khaz-Modan/Boltiz @WoW
Reply

Marsh Posté le 24-05-2007 à 10:42:20    

wedgeant a écrit :

[wedge@chimaera ~]$ echo $[2+3+4]
9


 
:o


expression regulierekituetou [:paletot]


---------------
ma conduite intérieure .:R | memaster pilote officiel de la HFR Badoit-Auchan F1 Team | zéro tracas, zéro blabla MMa.ster
Reply

Marsh Posté le 24-05-2007 à 12:24:05    

awk '{s+=$0}END{print s}'

Reply

Marsh Posté le 25-05-2007 à 08:43:55    

awk++

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed