Como eu crio um script bash que soma qualquer número de argumentos de linha de comando?

5

Como eu criaria um script bash que o usuário possa usar para somar qualquer quantidade de argumentos de linha de comando? Por exemplo, digamos que meu script seja chamado de soma:

sum 3

3

sum 3 5

8

sum 9 8 21

38

E assim por diante .. Eu percebo que vou ter que percorrer os argumentos da linha de comando e incrementá-los para o total, mas não tenho certeza de como fazer isso. Não sei como fazer referência ao argumento da segunda linha de comando para uma variável específica ou como obter o número total de argumentos da linha de comando.

    
por John 05.11.2013 / 07:26

3 respostas

12

Não há necessidade de bash , simples sh também:

#! /bin/sh - 
IFS=+; echo "$(($*))"

$* em shells POSIX, expande para a lista de parâmetros posicionais (nesse caso, os argumentos para o script) separados pelo primeiro caractere de $IFS (ou espaço se $IFS não estiver definido ou nada se $IFS está vazio). $((...)) é o operador de expansão aritmética interna do shell (observe que ele suporta números decimais, octais e hexadecimais)

Se você precisar de suporte a ponto flutuante, é necessário um shell diferente, como ksh93 ou zsh (não bash como bash suporta apenas a aritmética de inteiros), embora você também possa usar awk :

#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}

Isso usará os números de tipo double implementados pelo seu sistema. Os números de entrada devem ser ponto flutuante decimal ou notação de engenharia no estilo inglês (o delimitador de ponto flutuante é o caractere período , independentemente da localidade).

Alguns acham implementações como GNU awk quando POSIXLY_CORRECT está no ambiente também suportam hexadecimais incluindo com notações de expoentes binários. Ou com --non-decimal-data , entende octais e hexadecimais:

$ POSIXLY_CORRECT=1 ./sum  0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum  010
8
    
por 05.11.2013 / 10:51
8

Uma variante sem loop:

{ printf %d+ "$@"; echo 0; } | bc

Exemplo

Coloque o texto acima em um arquivo de script, sum .

#!/bin/bash

{ printf %d+ "$@"; echo 0; } | bc

Execute assim:

$ ./sum 4
4
$ ./sum 4 4 5
13
    
por 05.11.2013 / 08:25
7

Você pode usar a seguinte função bash:

sum() {
    local sum=0
    for arg in "$@"; do
        (( sum += arg ))
    done   
    echo $sum
}
    
por 05.11.2013 / 07:46