0

I am having a csv file with Header. I would like to create a bash script without using AWK to calculate the sum of let's say the 6th column if the variable on the column 13 equals to an input that I will pass via CMD.

File looks like:

IDENTIF,RIVER,LOCATION,ERECTED,PURPOSE,LENGTH,LANES,CLEAR-G,T-OR-D,MATERIAL,SPAN,REL-L,TYPE
E2,A,25,1819,HIGHWAY,1037,2,N,THROUGH,WOOD,SHORT,S,WOOD
E7,A,27,1840,HIGHWAY,990,2,N,THROUGH,WOOD,MEDIUM,S,WOOD
E16,A,25,1859,HIGHWAY,1030,2,N,THROUGH,IRON,MEDIUM,S-F,SUSPEN

So I would like for example if I execute script.sh WOOD , to print the sum of the 6th columns for the values in column 13 that equal to WOOD.

I have seen many solutions using AWK and solving it immediately. I was hoping how would you do the same without it.

Code I tried:

#!/bin/bash

skip_line = 0 total_length = 0 while IFS=, read -r -a fields do if [ $skip_line eq 0 ] then skip_line = $(($skip_line + 1)) continue fi

if [ ${fields[12]} == $1 ] then total_length = $(($total_length + ${fields[5]})) fi done < file.csv

echo "$total_length"

αғsнιη
  • 41,407

2 Answers2

0

SMOP.

First, use grep to select the lines, use cut to extract the field, and sum the values.

Untested

#!/bin/bash
pat="$1"
export total=0
grep ",$pat," file.txt |\
  cut -d, -f6 |\
  while read num ; do
    total=$total + $num
  done
echo "$total"
waltinator
  • 4,865
0

Before considering doing it this way, please see Why is using a shell loop to process text considered bad practice?

Nevertheless, your attempt is close (one obvious issue is the whitespace around the = in your total_length assignment).

#!/bin/bash

sum=0 while IFS=, read -a fields; do if [[ ${fields[12]} = "$1" ]]; then (( sum += fields[5] )) fi done < file.csv

printf 'sum: %d\n' "$sum"

You can shorten the if..then..fi using short-scircuit logic if you prefer ex.

[[ ${fields[12]} = "$1" ]] && (( sum += fields[5] ))

There's no need to skip the header line explicitly since it will fail the ${fields[12]} = "$1" test.

steeldriver
  • 81,074