Como posso resumir rapidamente todos os números em um arquivo?

16

Cada linha contém texto e números em uma coluna. Eu preciso calcular a soma dos números em cada linha. Como eu posso fazer isso? Thx

example.log contém:

time=31sec
time=192sec
time=18sec
time=543sec

A resposta deve ser 784

    
por Jack 27.05.2015 / 20:08

10 respostas

18

Se a sua opção grep support -o , você pode tentar:

$ grep -o '[[:digit:]]*' file | paste -sd+ - | bc
784

POSIXly:

$ printf %d\n "$(( $(tr -cs 0-9 '[\n*]' <file | paste -sd+ -) ))"
784
    
por 27.05.2015 / 20:23
16

Com uma versão mais recente (4.x) do GNU awk :

awk 'BEGIN {FPAT="[0-9]+"}{s+=$1}END{print s}'

Com outros awk s, tente:

awk -F '[a-z=]*' '{s+=$2}END{print s}'
    
por 27.05.2015 / 20:14
10
awk -F= '{sum+=$2};END{print sum}'
    
por 28.05.2015 / 06:38
7

Outro GNU awk one:

awk -v RS='[0-9]+' '{n+=RT};END{print n}'

Um perl um:

perl -lne'$n+=$_ for/\d+/g}{print$n'

Um POSIX um:

tr -cs 0-9 '[\n*]' | grep . | paste -sd + - | bc
    
por 27.05.2015 / 23:14
6
sed 's/=/ /' file | awk '{ sum+=$2 } END { print sum}'
    
por 27.05.2015 / 23:07
4

Você pode tentar isso:

awk -F"[^0-9]+" '{ sum += $2 } END { print sum+0; }' file
    
por 27.05.2015 / 20:17
3

Todos postaram incríveis awk de respostas, que eu gosto muito.

Uma variação para @cuonglm substituindo grep por sed :

sed 's/[^0-9]//g' example.log | paste -sd'+' - | bc
  1. O sed retira tudo, exceto os números.
  2. O comando paste -sd+ - une todas as linhas como uma única linha
  3. O bc avalia a expressão
por 28.05.2015 / 01:45
3

Você deve usar uma calculadora.

{ tr = \ | xargs printf '[%s=]P%d+p' | dc; } <infile 2>/dev/null

Com suas quatro linhas impressas:

time=31
time=223
time=241
time=784

E mais simplesmente:

tr times=c '    + p' <infile |dc

... que imprime ...

31
223
241
784

Se a velocidade é o que você está procurando, então dc é o que você quer. Tradicionalmente, era o compilador de bc - e ainda é para muitos sistemas.

    
por 28.05.2015 / 06:38
3

Através do python3,

import re
with open(file) as f:
    m = f.read()
    l = re.findall(r'\d+', m)
    print(sum(map(int, l)))
    
por 28.05.2015 / 06:14
3

Solução bash pura (Bash 3 +):

while IFS= read -r line; do                   # While it reads a line:
    if [[ "$line" =~ [0-9]+ ]]; then      # If the line contains numbers:
        ((counter+=BASH_REMATCH[0]))          # Add the current number to counter
    fi                                    # End if.
done                                  # End loop.

echo "Total number: $counter"         # Print the number.
unset counter                         # Reset counter to 0.

Versão resumida:

while IFS= read -r l; do [[ "$l" =~ [0-9]+ ]] && ((c+=BASH_REMATCH)); done; echo $c; c=0
    
por 30.05.2015 / 23:05