Bash - add values ​​in a row based on a column

The second column in my csv file has duplicates. I want to add the related values ​​from column 1 based on these duplicates.

Csv example:

56,  cc=DK
49,  cc=US
34,  cc=GB
32,  cc=DE
32,  cc=NZ
31,  cc=DK
31,  cc=GB
31,  cc=GB

Result:

96,  cc=GB # where 96 = 34+31+31
87,  cc=DK # where 87 = 56+31
32,  cc=DE
32,  cc=NZ
+4
source share
3 answers

You can use associative arrays in awk:

awk '{s[$2]+=$1}END{for(k in s)print s[k]", ",k}' inFile

Extending this for readability and using sum/key, rather than s/k:

{                                 # Do for each line.
    sum[$2] += $1                 # Add first field to accumulator,
                                  #   indexed by second field.
                                  #   initial value is zero.
}
END {                             # Do this bit when whole file processed.
    for (key in sum)              # For each key like cc=US:
        print sum[key] ", " key   # Output the sum and key.
}

Here the sample runs in my field:

pax$ echo;echo '56,  cc=DK
49,  cc=US
34,  cc=GB
32,  cc=DE
32,  cc=NZ
31,  cc=DK
31,  cc=GB
31,  cc=GB' | awk '{s[$2]+=$1}END{for(k in s)print s[k]", "k}'

32, cc=DE
96, cc=GB
32, cc=NZ
49, cc=US
87, cc=DK

, , 999, ( ), , awk , . , 45xyzzy 45 , , 49, 49.

+2

Perl:

perl -ane '$h{ $F[1] } += $F[0] }{ print "$h{$_}\t$_\n" for keys %h' input.csv

:

  • -n
  • -a @F
  • -% h (2 nd). .
  • }{ ( " Eskimo" ) , (-n), , .
+1

awk , , , , , .

, sqlite.

:

  • :

    $ cat <(echo "num, name") originalInput.txt | tr -d ' ' > input.csv
    
  • sqlite db:

    $ sqlite3 --batch temp.db <<EOF!
    .mode csv
    .import input.csv input
    EOF!
    
  • db:

    $sqlite3 temp.db 'SELECT sum(num), name FROM input GROUP BY name'
    32|cc=DE
    87|cc=DK
    96|cc=GB
    32|cc=NZ
    49|cc=US
    

sqlite3, . csv, .

, , , , .

0
source

All Articles