简体   繁体   中英

make math operation from multiple files with shell scripting

I have multiple files, let's say

fname1 contains:

red=5
green=10
yellow=2

fname2 contains:

red=10
green=2
yellow=2

fname3 contains:

red=1
green=7
yellow=4

I want to write script that read from these files, sum the numbers for each colour, and redirect the sums into new file.

New file contains:

red=16
green=19
yellow=8

[ awk ] is your friend :

awk 'BEGIN{FS="=";}
            {color[$1]+=$2}
     END{
         for(var in color)
          printf "%s=%s\n",var,color[var]
        }' fname1 fname2 fname3 >result

should do it.


Demystifying above stuff

  • Anything that is include inside '' is the awk program.
  • Stuff inside BEGIN will be executed only once, ie in the beginning
  • FS is an awk built-in variable which stands for field separator.
  • Setting FS to = means awk will use = to delimit the fields/columns.
  • By default awk considers each line as a record.
  • In that case you have two fields denoted by $1 and $2 in each record having = as the delimiter.
  • {color[$1]+=$2} creates(if not already exist) an associative array with color name as the key and += adds the value of the field2 to this array element. Remember, associative arrays at the time of creation are initilized to zero.
  • This is repeated for the three files fname1, fname2, fname3 fed into awk
  • Anything inside END{} will be executed only at last, ie just before exit.
  • for(var in color) is a the style of forloop used to parse an associative array.
  • Here var will be a key and color[key] points to value.
  • printf "%s=%s\\n",var,color[var] is self explained.

Note

  • If all the filenames start with fname you can even put fname* instead of fname1 fname2 fname3
  • This assumes that there are no blank lines in any file

Because your source files are valid shell code. You can just source them (if they are from a trusted source) and accumulate them using Shell Arithmetic .

#!/bin/bash

sum_red=0
sum_green=0
sum_yellow=0

for file in "$@";do
    . ${file}
    let sum_red+=red
    let sum_green+=green
    let sum_yellow+=yellow
done

echo "red=$sum_red
green=$sum_green
yellow=$sum_yellow"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM