我需要编写一个脚本,它将在不同行中添加同一字符串的值。
例如,当文件包含以下内容时:
abc,10
xyz,20,
abc,30,
ghd,40
xyz,10
脚本应该检查文件中的匹配字符串abc
等xyz
并添加它的值并将输出重定向到新文件。
输出应该是:
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
如果您想要排序输出,请通过管道。