Search code examples
bashshellcut

Reading a file in a shell script and selecting a section of the line


This is probably pretty basic, I want to read in a occurrence file.

Then the program should find all occurrences of "CallTilEdb" in the file Hendelse.logg:

CallTilEdb         8
CallCustomer       9
CallTilEdb         4
CustomerChk        10
CustomerChk        15
CallTilEdb         16

and sum up then right column. For this case it would be 8 + 4 + 16, so the output I would want would be 28.

I'm not sure how to do this, and this is as far as I have gotten with vistid.sh:

#!/bin/bash
declare -t filename=hendelse.logg
declare -t occurance="$1"
declare -i sumTime=0

while read -r line
do
    if [ "$occurance" = $(cut -f1 line) ]       #line 10
    then
        sumTime+=$(cut -f2 line)
    fi
done < "$filename"

so the execution in terminal would be

vistid.sh CallTilEdb

but the error I get now is:

/home/user/bin/vistid.sh: line 10: [: unary operator expected

Solution

  • You have a nice approach, but maybe you could use awk to do the same thing... quite faster!

    $ awk -v par="CallTilEdb" '$1==par {sum+=$2} END {print sum+0}' hendelse.logg
    28
    

    It may look a bit weird if you haven't used awk so far, but here is what it does:

    • -v par="CallTilEdb" provide an argument to awk, so that we can use par as a variable in the script. You could also do -v par="$1" if you want to use a variable provided to the script as parameter.
    • $1==par {sum+=$2} this means: if the first field is the same as the content of the variable par, then add the second column's value into the counter sum.
    • END {print sum+0} this means: once you are done from processing the file, print the content of sum. The +0 makes awk print 0 in case sum was not set... that is, if nothing was found.

    In case you really want to make it with bash, you can use read with two parameters, so that you don't have to make use of cut to handle the values, together with some arithmetic operations to sum the values:

    #!/bin/bash
    declare -t filename=hendelse.logg
    declare -t occurance="$1"
    declare -i sumTime=0
    
    while read -r name value                  # read both values with -r for safety
    do
        if [ "$occurance" == "$name" ]; then  # string comparison
           ((sumTime+=$value))                # sum
        fi
    done < "$filename"
    
    echo "sum: $sumTime"
    

    So that it works like this:

    $ ./vistid.sh CallTilEdb
    sum: 28
    $ ./vistid.sh CustomerChk
    sum: 25