如何在文件中添加聚合数字

如何在文件中添加聚合数字

我需要编写一个脚本,它将在不同行中添加同一字符串的值。

例如,当文件包含以下内容时:

abc,10
xyz,20,
abc,30,
ghd,40
xyz,10

脚本应该检查文件中的匹配字符串abcxyz并添加它的值并将输出重定向到新文件。

输出应该是:

abc,40,
xyz,30,
ghd,40

我们可以为此编写一个脚本吗?任何输入都会有帮助。

答案1

Perl 中很简单:使用散列来存储运行总和。

perl -laF/,/ -ne '
    $h{ $F[0] } += $F[1];
    }{
    print "$_,$h{$_}" for keys %h;
' input-file > output-file
  • -n逐行读取输入
  • -l添加换行符print
  • -a将每个输入行拆分为 @F 数组
  • -F/,/告诉-a以逗号分隔
  • }{是“爱斯基摩问候语”运算符,它将循环-n与将在输入末尾运行的代码分开。

答案2

怎么样bash

for i in $(cut -d ',' -f1 FILE  | sort | uniq)
do
    echo -n "$i", &&
    echo -n $(grep "^$i," FILE | cut -d',' -f2 | paste -sd+ - | bc)
    echo $(echo "$i" | grep -E -o ",$") || echo
done

或者如果你会错过,

for i in $(cut -d ',' -f1 FILE  | sort | uniq)
do
    echo -n "$i", &&
    echo -n $(grep "^$i," FILE | cut -d',' -f2 | paste -sd+ - | bc) &&
    grep -E -o "$i,[0-9]+,$" FILE >/dev/null && echo ',' || echo
done

或者,如果您想保存令牌的顺序:

for i in $(cut -d ',' -f1 FILE  | awk '!seen[$0]++')
do
    echo -n "$i", &&
    echo -n $(grep "^$i," FILE | cut -d',' -f2 | paste -sd+ - | bc) &&
    grep -E -o "$i,[0-9]+,$" FILE >/dev/null && echo ',' || echo
done

替换FILE为实际的文件名。

答案3

awk -F, -v OFS=, '{
          str[$1]+=$2;
          next
     }

     END {
          for (s in str) {
              print s, str[s]
          } 
     }' filename

构建一个关联数组(即由字符串而不是整数作为键),其中包含每个字符串(字段 1)的累积总数。

当它读取所有输入时,它会打印出数组的每个元素。

ghd,40
abc,40
xyz,30

sort如果您想要排序输出,请通过管道。

相关内容