ファイル内の行の数値を合計するにはどうすればよいですか


24

次のようなファイルがあります。

1
3
4
1
4
3
1
2

この合計(つまり1 + 3 + 4 + 1 + 4 + 3 + 1 + 2 = 19)を見つけるにはどうすればよいですか?


1
コンテキストとして、Ask Ubuntuにあるスタック交換APIのバッジの数を数えています。
ティム

cat badges.json | grep -o '"award_count":[0-9],"rank":"gold"' | grep -o [0-9]
ティム

今ではAPIにbadge_countメソッドがあることに気付きました。
ティム

APIからバッジをカウントしている場合、APIのクエリに使用している言語はこれを実行できません(python、javascript)?
Braiam

回答:


42

bcから少しの助けを借りて、セパレーターとしてpaste単一の行を取得します+

paste -sd+ file.txt | bc

grep静的ファイルの代わりに(または他のコマンド)の出力を使用するには、grepのSTDOUTをSTDINに渡しますpaste

grep .... | paste -sd+ | bc

例:

% cat file.txt            
1
3
4
1
4
3
1
2

% paste -sd+ file.txt | bc
19

% grep . file.txt | paste -sd+ | bc
19

あなたが使用する必要がある場合bash、あなたは、ファイルの内容を保存し、その後の要素を反復処理するために、配列を使用するかは、行毎にファイルを読み込み、行ごとに合計を行うことができ、第2のアプローチは、より効率的に次のようになります。

$ time { nums=$(<file.txt); for i in ${nums[@]}; do (( sum+=i )); done; echo $sum ;}
19

real    0m0.002s
user    0m0.000s
sys 0m0.000s

$ time { while read i; do (( sum+=i )); done <file.txt; echo $sum ;}
19

real    0m0.000s
user    0m0.000s
sys 0m0.000s

うーん、いいね。質問に変更することが申し訳ありません:1行のようにそれを私はgrepの出力を受け入れるために、これを修正することができます(または作るcat file.txt | bc
ティム・

@Tim編集内容を確認
-heemayl

Ta、それは簡単でした!
ティム

2
私が使用しなければならなかった別の答えで私が発見するまで、stdinの方法は私のために機能しませんでしたpaste -sd+ -。それを修正してください。
ゼロス

19

awkも使用できます。「hello」という単語を含む* .txtファイルの行の総数を数えるには:

grep -ch 'hello' *.txt | awk '{n += $1}; END{print n}'

ファイル内の数字を単純に合計するには:

awk '{n += $1}; END{print n}' file.txt

ただし、その行の値が「4」の場合、4はカウントされません。1をカウントします
ティム

いいえ、4をカウントします
。– CrazyApe84

ファイル内の数値の合計が必要です。これはそうですか?
ティム

質問をgrepの出力に変更したと思います。私はいくつかの仮定をしていました。ファイル内の値を単純に合計する方法を追加します。
CrazyApe84

2
うん。これは本当にheemaylの答えと同じ答えですが、pasteやbcの代わりにawkを使用するため、最終的には柔軟性が高まります。それでも、彼の答えはよく、彼は最初だったので、彼はあなたの投票に値します!
CrazyApe84

7

numsumパッケージから使用num-utils

(必要になる場合がありますsudo apt-get install num-utils

このコマンドnumsumは、デフォルトで必要なことを実行します。

$ numsum file.txt 
19

テスト番号を1行ずつ読み取りますstdin

$ printf '
1 
3
4
1
4
3
1
2' | numsum
19

または、1行から読み取ります。

$ printf '1 3 4 1 4 3 1 2' | numsum -r
19


その他のユーティリティ

このパッケージには、もっと有名になるに値する数値処理用のその他のユーティリティがいくつか含まれています。

numaverage   - find the average of the numbers, or the mode or median
numbound     - find minimum of maximum of all lines
numgrep      - to find numbers matching ranges or sets
numinterval  - roughly like the first derivative
numnormalize - normalize numbers to an interval, like 0-1
numrandom    - random numbers from ranges or sets, eg odd.  
numrange     - similar to seq
numround     - round numbers up, down or to nearest

より一般的な計算機命令numprocess
入力ライン上の番号に、コマンドラインからの発現を適用します。


1

を使用してawk、行ごとのパターンでファイルをスキャンおよび処理するのに役立つネイティブLinuxアプリケーションを使用できます。あなたの質問に対して、これはあなたが望むものを生成します:

awk 'BEGIN { sum=0 } { sum+=$1 } END {print sum }' file.txt

パイプも受け入れます:

cat file.txt | awk 'BEGIN { sum=0 } { sum+=$1 } END {print sum }'

BEGIN{}ブロックは不要です。CrazyApe84の答えをご覧ください。
テルドン

それはこの問題に冗長ですが、私は教訓的な目的のためそれを含めることを好みました。
グワラ

しかし、それは何を教えていますか?awkCではなく、すべての問題に対して冗長です。使用する前に変数を設定する必要はありません。試してくださいawk 'BEGIN{print c+=1}'
テルドン

BEGIN {}ブロックは、変数を初期化するためだけに設計されたものではありません。設計仕様に参加します。そのため、一部の問題では必要になる場合があります。
グワラ

0

これは、bashスクリプトのかなり簡単な使用法です。

SUM=0; for line in `cat file.txt`; do SUM=$((SUM + line)); done

これは、現在のソリューションよりもはるかにシンプルで最小限のツールセットです。
デット

0

Perlソリューション:

$ perl -lnae '$c+=$_;END{print $c}' input.txt                                                                            
19

上記は、複数のファイルにわたるすべての数値を合計できます。

$ perl -lnae '$c+=$_;END{print $c}' input.txt input2.txt                                                                 
34

個々のファイルの数値の合計を表示するコマンドラインで指定された複数のファイルの場合、次の操作を実行できます。

$ perl -lnae '$c+=$_;if(eof){printf("%d %s\n",$c,$ARGV);$c=0}' input.txt input2.txt                                      
19 input.txt
15 input2.txt


0

簡単なアプローチは、シェルの組み込み機能を使用することです。

SUM=0; while read N; do SUM=$((SUM+N)); done </path/to/file
echo $SUM

これは、ファイルを行ごとに読み取り、合計して結果を出力します。

パイプを使用し、最初の行のみを使用する場合、次のように機能します。

SUM=0
your_command | while read -r LINE; do for N in $LINE; do break; done; SUM=$((SUM+N)); done
echo $SUM

最初の要素の取得は次のように行われます。

LIST="foo bar baz"
for OBJ in $LIST; do break; done
echo $OBJ

foo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.