ghostrider
ghostrider

Reputation: 5259

reading data from a file using bash and getting sum for some columns with awk

Lets say I want to collect some statistics over a .txt file that looks like this:

misses 15
hit 18
misses 20
hit 31

I wrote a bash script that just prints every line:

#!/bin/bash 
while read line           
do           
    echo $line 
done <t.txt 

What I want now is this: the example is in pseudocode:

read every line
   if first column is miss add the number to total misses
   if hits add the number to total hits

print total hits, and total misses in a file

I have searched and this can be done with awk. Can you help to do this with awk?

Upvotes: 0

Views: 1698

Answers (4)

chepner
chepner

Reputation: 530920

declare misses=0 hit=0
while read var val; do
    let $var+=val
done < f.txt
echo "Misses: $misses"
echo "Hits: $hit"

Upvotes: 0

Vijay
Vijay

Reputation: 67211

awk '/misses/||/hit/{a[$1]+=$2}END{print "total hits",a["hit"],",and total misses",a["misses"]}' your_file

tested:

> cat temp
misses 15
hit 18
misses 20
hit 31
hait 31
> awk '/misses/||/hit/{a[$1]+=$2}END{print "total hits",a["hit"],",and total misses",a["misses"]}' temp
total hits 49 ,and total misses 35

Upvotes: 2

choroba
choroba

Reputation: 241758

Just translate your algorithm to bash:

#!/bin/bash 
while read what count ; do           
    case $what in
        (hit)    let total_h+=count ;;
        (misses) let total_m+=count ;;
        (*)      echo Invalid input >&2; exit ;;
    esac
done < t.txt
echo Hits: $total_h, Misses: $total_m

Upvotes: 2

peteches
peteches

Reputation: 3609

No need for any bash gubbins, awk will do it all

awk 'BEGIN{ hits=0; misses=0; }/^hit/{ hits+=$NF}; /^misses/{misses=$NF}; END {print "Hits: " hits "\nMisses: " misses }' txtfile

Ok 3 parts to this one liner:

BEGIN{ hits=0; misses=0; }

Is only run once before awk reads any lines from txtfile and initialises the two variables hits and misses.

/^hits/{ hits+=$NF}; /^misses/{misses=$NF};

is run on each line, if the line begins with hits the last column is added to the hits variable and if it begins with misses then the misses variables get the last column added to it.

END {print "Hits: " hits "\nMisses: " misses' }

Runs only once all lines have been processed and prints out a message detailing hits and misses.

Upvotes: 2

Related Questions