unset -v prev
sort file |
{
while read -r key value; do
if [ "$key" != "${prev-$key}" ]; then
# prev is set and different from $key
printf '%s:%d\n' "$prev" "$sum"
sum=0
fi
prev=$key
sum=$(( sum + value ))
done
if [ "${prev+set}" = set ]; then
printf '%s:%d\n' "$prev" "$sum"
fi
}
#!/bin/bash
declare -i SECOND
while read first second; do
if [ -z $FIRST ] || [ $first = $FIRST ]; then
SECOND+=second
else
echo $FIRST:$SECOND
SECOND=second
fi
FIRST=$first
done < <(sort file)
echo $FIRST:$SECOND
我将假设输入总是每行包含两个字段。
您可以使用 GNU
datamash
实用程序对数据进行排序,按第一个字段对其进行分组,然后计算每个组的第二个字段的总和:在这里,
-s
对输入进行排序,-W
使实用程序将任何连续的空白字符视为字段分隔符,并将--output-delimiter=:
输出分隔符设置为:
字符。其余的告诉datamash
按第一个字段分组并计算每个组的第二个字段的总和。给定名为 的文件中问题中的输入
file
,这将产生以下输出:您也可以通过任何其他方式解决此问题。最简单的计算解决方案是使用
awk
:在这里,我们使用关联数组 ,
sum
来保存第一个字段中每个字符串的总和。该END
模块在输入结束时执行,并将计算的总和与字符串一起输出。请注意,此解决方案还假设第一个字段是一个不包含空格字符的单词,如问题所示。
使用 shell 循环,从原始文件中读取已排序的行,每当遇到新的第一个字段时打印并重置第二个字段的总和:
相关:为什么使用 shell 循环处理文本被认为是不好的做法?
如果您正在处理大文件,请考虑使用
sort
andawk
这样我们就不会分配巨大的数组来在 RAM 中存储键和值。通常我会写一个类似的空白,并在生产中将所有变量放在引号中。
输出