web-dev-qa-db-ja.com

ファイル内のすべての数値をすばやく合計するにはどうすればよいですか?

各行の1列にテキストと数値が含まれています。各行の数値の合計を計算する必要があります。どうやってやるの?どうも

example.logには以下が含まれます:

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

答えは784である必要があります

16
Jack

grepサポート-oオプション、次を試すことができます:

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

POSIXly:

$ printf %d\\n "$(( $(tr -cs 0-9 '[\n*]' <file | paste -sd+ -) ))"
784
18
cuonglm

GNU awkの新しいバージョン(4.x)の場合:

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

他のawksを試してください:

awk -F '[a-z=]*' '{s+=$2}END{print s}'
16
Janis
awk -F= '{sum+=$2};END{print sum}'
10
snth

別のGNU awk one:

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

Perl one:

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

POSIXのもの:

tr -cs 0-9 '[\n*]' | grep . | paste -sd + - | bc
7
sed 's/=/ /' file | awk '{ sum+=$2 } END { print sum}'
6
user2570505

あなたはこれを試すことができます:

awk -F"[^0-9]+" '{ sum += $2 } END { print sum+0; }' file
4
taliezin

みんなが素晴らしいawk回答を投稿してくれて、とても気に入っています。

@cuonglmのバリエーションで、grepsedに置き換えます。

sed 's/[^0-9]//g' example.log | paste -sd'+' - | bc
  1. sedは、数値以外のすべてを取り除きます。
  2. paste -sd+ -コマンドは、すべての行を1つの行として結合します
  3. bcは式を評価します
4
Stephen Quan

Python3を通じて、

import re
with open(file) as f:
    m = f.read()
    l = re.findall(r'\d+', m)
    print(sum(map(int, l)))
3
Avinash Raj

電卓を使ってください。

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

印刷する4行で:

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

そしてもっと簡単に:

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

...印刷する...

31
223
241
784

スピードがあなたの求めるものであるなら、dcがあなたの望んでいるものです。伝統的にはbcのコンパイラーでしたが、今でも多くのシステムで使用されています。

3
mikeserv

純粋なbashソリューション(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.

ショートバージョン:

while IFS= read -r l; do [[ "$l" =~ [0-9]+ ]] && ((c+=BASH_REMATCH)); done; echo $c; c=0
3
Helio