sum列依赖于linux中的另一列

时间:2016-04-05 10:36:54

标签: linux shell unix awk scripting

我有2个文件,我想根据相同的秒数求和第一列。如果没有时间意味着它是零,如果时间重复,则意味着所有相同的时间总和,但如何,请帮助我。

第一档:

 16 /home/appuser<Apr 4, 2016 11:24:46 PM EEST
  2 /home/appuser<Apr 4, 2016 11:24:47 PM EEST
  3 /home/appuser<Apr 4, 2016 11:24:48 PM EEST
  1 /home/appuser<Apr 4, 2016 11:24:50 PM EEST
  3 /home/appuser<Apr 4, 2016 11:24:51 PM EEST
  7 /home/appuser<Apr 4, 2016 11:24:52 PM EEST
  9 /home/appuser<Apr 4, 2016 11:24:54 PM EEST
  8 /home/appuser<Apr 4, 2016 11:24:54 PM EEST
  5 /home/appuser<Apr 4, 2016 11:24:55 PM EEST

第二档:

  6 /home/appuser<Apr 4, 2016 11:24:46 PM EEST
  4 /home/appuser<Apr 4, 2016 11:24:49 PM EEST
  7 /home/appuser<Apr 4, 2016 11:24:50 PM EEST
  5 /home/appuser<Apr 4, 2016 11:24:50 PM EEST
 10 /home/appuser<Apr 4, 2016 11:24:52 PM EEST
  6 /home/appuser<Apr 4, 2016 11:24:52 PM EEST
 10 /home/appuser<Apr 4, 2016 11:24:55 PM EEST
  5 /home/appuser<Apr 4, 2016 11:24:57 PM EEST

输出:

 22 /home/appuser<Apr 4, 2016 11:24:46 PM EEST
  2 /home/appuser<Apr 4, 2016 11:24:47 PM EEST
  3 /home/appuser<Apr 4, 2016 11:24:48 PM EEST
  4 /home/appuser<Apr 4, 2016 11:24:49 PM EEST
 13 /home/appuser<Apr 4, 2016 11:24:50 PM EEST
  3 /home/appuser<Apr 4, 2016 11:24:51 PM EEST
 23 /home/appuser<Apr 4, 2016 11:24:52 PM EEST
  0 /home/appuser<Apr 4, 2016 11:24:53 PM EEST
 17 /home/appuser<Apr 4, 2016 11:24:54 PM EEST
 15 /home/appuser<Apr 4, 2016 11:24:55 PM EEST
  0 /home/appuser<Apr 4, 2016 11:24:56 PM EEST
  5 /home/appuser<Apr 4, 2016 11:24:57 PM EEST

3 个答案:

答案 0 :(得分:1)

由于需要插入0和缺少日期,这非常棘手。

这是一个可以使用sort的awk:

awk -F '<| /' '{
   cmd="date -d \"" $3 "\" +%s"
   cmd | getline ts
   close(cmd)

   if (p>0 && (ts-p)>1) {
      for(i=p+1; i<ts; i++) {
         sums[i]=0
         cmd="TZ=EET date -d @" i " \"+%b%e, %Y %r %Z\""
         cmd | getline tsi
         close(cmd)
         data[i]= "/" c2 "<" tsi
      }
   }

   sums[ts]+=$1
   data[ts]="/" $2 "<" $3
   p = ts
   c2 = $2
}
END {
   for (i in sums)
      printf "%4d%s%s\n", sums[i], OFS, data[i]
}' <(sort -t'<' -k2 file1 file2)

<强>输出:

  22 /home/appuser<Apr 4, 2016 11:24:46 PM EEST
   2 /home/appuser<Apr 4, 2016 11:24:47 PM EEST
   3 /home/appuser<Apr 4, 2016 11:24:48 PM EEST
   4 /home/appuser<Apr 4, 2016 11:24:49 PM EEST
  13 /home/appuser<Apr 4, 2016 11:24:50 PM EEST
   3 /home/appuser<Apr 4, 2016 11:24:51 PM EEST
  23 /home/appuser<Apr 4, 2016 11:24:52 PM EEST
   0 /home/appuser<Apr 4, 2016 11:24:53 PM EEST
  17 /home/appuser<Apr 4, 2016 11:24:54 PM EEST
  15 /home/appuser<Apr 4, 2016 11:24:55 PM EEST
   0 /home/appuser<Apr 4, 2016 11:24:56 PM EEST
   5 /home/appuser<Apr 4, 2016 11:24:57 PM EEST

答案 1 :(得分:0)

尝试使用以下code.hope帮助

$ awk '{a[$5]+=$1; sub(/[0-9]+/,"",$1); line[$5]=$0}
    END{for(k in a) printf "%2d %s\n",a[k],line[k]}' first second


13  /home/appuser<Apr 4, 2016 11:24:50 PM EEST
 3  /home/appuser<Apr 4, 2016 11:24:51 PM EEST
23  /home/appuser<Apr 4, 2016 11:24:52 PM EEST
17  /home/appuser<Apr 4, 2016 11:24:54 PM EEST
15  /home/appuser<Apr 4, 2016 11:24:55 PM EEST
22  /home/appuser<Apr 4, 2016 11:24:46 PM EEST
 2  /home/appuser<Apr 4, 2016 11:24:47 PM EEST
 5  /home/appuser<Apr 4, 2016 11:24:57 PM EEST
 3  /home/appuser<Apr 4, 2016 11:24:48 PM EEST
 4  /home/appuser<Apr 4, 2016 11:24:49 PM EEST

答案 2 :(得分:0)

在您的原始问题中,您输出的输入包含总和为0的时间,我不确定其来自何处 - 假设您没有提供其他数据不得不担心以下内容将根据匹配列二进制总结第一列。这可以扩展到您需要的任意数量的文件,只需将它们添加到输入cat中的文件列表 - &gt; <(cat f1.txt f2.txt f3.txt ... fn.txt)

unset myarr && declare -A myarr 
while read a; do  
 col1=$(cut -d' ' -f1 <<< "${a}") 
 col2=$(cut -d' ' -f3- <<< "${a}") 
 let myarr["${col2}"]+="${col1}"
done < <(awk '{var=$1; $1=""; print var,$0}' <(cat f1.txt f2.txt)) 
for a in "${!myarr[@]}"; do echo "${myarr["$a"]} ${a}"; done