如何计算多个文件中类似数据的特定字段?

时间:2013-05-27 22:17:11

标签: bash

我有一个带结构的多个文件

1:

57  string1 string2   0   200   0     0    11
50  string6 string7   0   656   676   12   0

2:

11  string3 string4   2   45    86    0    0
57  string1 string2   0   343   0     0    11
50  string6 string7   0   565   676   12   0

我需要计算所有行中所有行的所有数字的总和,并为所有文件中的所有数据行使用相同的第一个字段。

例如,对于以50开头的行,它将是656 + 565 = 1221的总和。对于数字57,分别为343 + 200 = 543.之后我想显示具有最大总金额的字符串格式(例如,50):“50 string1 string2 1221”。

我只能使用这些命令:printf,echo,wc,tail,head,grep,sort,uniq,cut,tee,tr,read,不使用临时文件。

我制作了一个脚本,但它计算错误的值:在文件输入上,它只是计算文件中所有行的字段总和,我需要如上所述..   怎么做(或者更确切地说,如何修复它以使其工作)?这是脚本:

#! /bin/bash

function findMax {

  for file in $* ; do
    cat $file | sort -bd | calcSums 
  done      
} 

function calcSumForSimilar {

  local sum_for_similar=0

  while read -a line ; do
    let sum_for_similar+=${line[4]}      
  done

  echo $sum_for_similar      
}

function calcSums {

  while read -a line; do
    sum=$(cat "${line[@]}"  | grep ${line[0]} | calcSumForSimilar)
  done

  echo ${line[0]} ${line[1]} ${line[2]} $sum
} 

findMax $*

谢谢!

2 个答案:

答案 0 :(得分:3)

您可以使用awk:

awk '{s[$1]+=$5} END{ for (x in s) { print x, s[x]}}' in1 in2

没有awk:

for k in $(cut -f1 -d' ' in1 in2 | sort | uniq); do 
  s=0; 
  for v in $(grep "^$k" in1 in2 | cut -f10 -d' '); do 
    let s+=$v; 
  done; 
  echo $k $v 
done

答案 1 :(得分:1)

假设现代bash,只使用内置:

declare -A sum strings

# read all the files
while read f1 f2 f3 f4 f5 rest; do
  (( sum[f1] += f5 ))
  strings[f1]="$f2 $f3"
done << *

# calculate the max
max=-1
for key in "${!sum[@]}"; do
  if (( max < sum[key] )); then
    max=${sum[key]}
    max_key=$key
  fi
done