我有一个带有标题的 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"
测试失败。