如何在不使用Shell脚本创建临时文件的情况下计算列的总和?

时间:2018-11-08 00:23:01

标签: shell

为输入文件提供了如下数据:

id,name
10,abc
20,xyz
30,def

我正在尝试对id列中的值求和。

注意:我使用awk -v标头的原因是因为我有多个文件,所有这些文件的ID作为通用标头名称,但位置不同。

我期望的输出是id的总和(即,在上面的示例中,输出为60)。

下面的代码可以工作并返回预期的输出,但是我必须在代码中创建一个临时文件,然后计算总和。

不幸的是,我尝试了许多变体。

我想避免将数据写入临时文件intfile.txt,但卡住了。

赞赏任何解决方案/建议。

ps:我对shell脚本比较陌生,我知道代码编写得不好,但是我正在研究它。

#!/bin/bash
awk -v header="id" '
BEGIN { FS=","; a=0 }
NR == 1 { for (i=1;i<=NF;i++) { if ($i==header) { a=i }} }
a=NR > 1 && a>0 { print $a }' testfile.txt>intfile.txt
awk '{s+=$1}END{print s}' intfile.txt

2 个答案:

答案 0 :(得分:0)

#!/usr/bin/env bash

target="id"   # the field you want to sum
target_idx=   # the column number of that field
sum=0         # the sum that was found so far

{
  # first, just read the header...
  IFS=, read -r -a header
  for idx in "${!header[@]}"; do  # and look for the target field in it
    [[ ${header[$idx]} = $target ]] && { target_idx=$idx; break; }
  done
  [[ $target_idx ]] || { echo "ERROR: No $target field found" >&2; exit 1; }

  # then, iterate over other lines
  while IFS=, read -r -a line; do
    sum=$(( sum + ${line[$target_idx]} ))
  done
} <testfile.txt

echo "$sum"

请参见https://ideone.com/MOnpFM


一些参考文献:

答案 1 :(得分:0)

也尝试以下操作:

idline=$(grep id input.txt)
IFS=',' read -ra elem <<< "$idline"
idfld=0
for i in "${elem[@]}"; do
    idfld=$(($idfld+1))
    if [[ "$i" = "id" ]]
    then
        break;
    fi
done
gt=0
for num in `cat input.txt|grep "^[0-9]"|cut -d"," -f${idfld}`; do
    gt=$(($gt+$num ))
done
echo $gt