当另一列等于输入值时 Bash 脚本一列的总和

当另一列等于输入值时 Bash 脚本一列的总和

我有一个带有标题的 csv 文件。如果第 13 列上的变量等于我将通过 CMD 传递的输入,我想创建一个 bash 脚本,而不使用 AWK 来计算第六列的总和。

文件看起来像:

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

因此,例如,如果我执行 script.sh WOOD ,则打印第 13 列中等于 WOOD 的值的第 6 列的总和。

我见过很多使用 AWK 的解决方案并立即解决它。我希望如果没有它,你会如何做同样的事情。

我尝试过的代码:

#!/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"

答案1

SMOP。

首先,使用grep选择行,使用cut提取字段,并对值求和。

未经测试

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

答案2

在考虑这样做之前,请参阅为什么使用 shell 循环处理文本被认为是不好的做法?

=尽管如此,您的尝试已经很接近了(一个明显的问题是您的作业中周围的空白total_length)。

#!/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"

如果您愿意,可以缩短if..then..fi使用短路逻辑的时间。

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

无需显式跳过标题行,因为它会使${fields[12]} = "$1"测试失败。

相关内容