複数の浮動小数点列の合計を計算する方法

複数の浮動小数点列の合計を計算する方法

浮動小数点データを含む複数の列の合計を計算するシナリオがあります。

以下のコードは整数値には機能しますが、フローティングペイント値には機能しません。

コードはこのデータに完全に適合します。

ID|NAME|SAL|COST|PER|TAG

1|A|10|10|20|10|

1|B|10|15|20|10|

1|C|10|17|25|80|

1|D|115|110|20|100|

1|E|10|10|10|10|

パスワード:

#!/bin/bash
FILE="$1"
COLUMNS="${@:2}"
for col in $COLUMNS; do
  colnum=$(awk -v RS='|' '/'$col'/{ print NR; exit}' $FILE)
  awk '{FS="|"}{s+='$colnum'}END{print "'$col' ", s}' $FILE
done | column -t

上記のコードを使用して、次のデータの合計をどのように取得できますか?

ID|NAME|SAL|COST|PER|TAG

    1|A|9.234|123.12|20.123|67.1|

    1|B|10.12|153.234|20.90|190.34|

    1|C|8.234|17.01|25.777|80.09|

    1|D|11.2|11.222|10.1|10.00000|

    1|E|16.23|10.1|145.22|11.77278|

新しいコードが機能しません。

#!/bin/bash
FILE="$1"
COLUMNS="${@:2}"
for col in $COLUMNS; do
            awk -F'|' '{T+=$col} END { printf "%.10f\n", T }' $FILE
    done | column -t

ベストアンサー1

最初はシェルでこれをしないでください。しかし、awk.シェルでは浮動小数点演算を実行する方法がわかりません。

あなたのスクリプトは、解析するファイル名と考慮するフィールド名に対応する一連のパラメータを使用しているようです。

awk各列に対して2回呼び出すよりも効率的にこれを行うことができます。

BEGIN { OFS = FS = "|" }

FNR == 1 {
        # Handle the header row. Assuming "cols" is a FS-separated
        # string of column names that we want to sum, pick out the
        # column numbers that we want to process and put them in the
        # array "col". This also converts the "cols" string into a
        # corresponding "header" array.

        nf = split(cols, header)
        for (i = 1; i <= NF; ++i)
                for (j = 1; j <= nf; ++j)
                        if ($i == header[j])
                                col[j] = i
        next
}

{
        # Sum each column that we have enumerated in the "col" array.

        for (i = 1; i <= nf; ++i)
                sum[i] += $(col[i])
}

END {
        # Output a two row table containing only the headers that we
        # have summed over and the accumulated sums.

        $0 = ""

        for (i = 1; i <= nf; ++i)
                $i = header[i]
        print

        for (i = 1; i <= nf; ++i)
                $i = sum[i]
        print
}

以下を使用して、最初のファイルでこのコマンドを実行します。

$ awk -v cols="SAL|COST|PER|TAG" -f script.awk file1
SAL|COST|PER|TAG
155|162|95|210

同じ列を2回リストすると、2つの合計が発生します。

$ awk -v cols="SAL|SAL" -f script.awk file1
SAL|SAL
155|155

2番目のファイルでは:

$ awk -v cols="SAL|COST|PER|TAG" -f script.awk file2
SAL|COST|PER|TAG
55.018|314.686|222.12|359.303

使用後処理column -t:

$ awk -v cols="SAL|COST|PER|TAG" -f script.awk file2 | column -s '|' -t
SAL     COST     PER     TAG
55.018  314.686  222.12  359.303

これを簡単なスクリプトに入れます。

#!/bin/sh

infile=$1
shift

IFS='|'

awk -v cols="$*" -f script.awk "$infile" |
column -s '|' -t

次のように使用できます。

$ ./script.sh file1 PER TAG
PER  TAG
95   210

CSVkitなどのCSV認識ツールを使用して操作を実行することもできます。

csvstatCSVファイルのいくつかの基本的な「統計」を計算する機能。ファイルが正しい形式のCSVファイルであると仮定すると(各データ行に末尾の区切り|文字があるため)、各列の合計が渡される可能性があります。

$ csvstat --sum file1
  1. ID: None
  2. NAME: None
  3. SAL: 155
  4. COST: 162
  5. PER: 95
  6. TAG: 210
$ csvstat --sum file2
  1. ID: None
  2. NAME: None
  3. SAL: 55.018
  4. COST: 314.686
  5. PER: 222.12
  6. TAG: 359.30278

または単一列の場合:

$ csvstat --sum -c 'SAL' file2
55.018

おすすめ記事