我有一个包含以下记录的文件:
$ cat sample.txt
ABC,100
XYZ,50
ABC,150
QWE,100
ABC,50
XYZ,100
期望输出为:
$ cat output.txt
ABC,300
XYZ,150
QWE,100
我尝试了以下脚本:
PREVVAL1=0
SUM1=0
cat sam.txt | sort > /tmp/Pos.part
while read line
do
VAL1=$(echo $line | awk -F, '{print $1}')
VAL2=$(echo $line | awk -F, '{print $2}')
if [ $VAL1 == $PREVVAL1 ]
then
SUM1=` expr $SUM + $VAL2`
PREVVAL1=$VAL1
echo $VAL1 $SUM1
else
SUM1=$VAL2
PREVVAL1=$VAL1
fi
done < /tmp/Pos.part
我想要一个衬板命令来获取所需的输出。想要避免while循环概念。我只想在第一列相同的地方添加数字,并在一行中显示。
答案 0 :(得分:2)
awk -F, '{a[$1]+=$2} END{for (i in a) print i FS a[i]}' sample.txt
输出
QWE,100
XYZ,150
ABC,300
对每一行执行第一部分,并创建一个关联数组。 END
部分将打印此数组。
答案 1 :(得分:1)
这是awk
单线:
awk -F, -v OFS=, '{sum[$1]+=$2} END {for (key in sum) print key, sum[key]}' sample.txt > output.txt
sum[$1] += $2
创建一个关联数组,其键是第一个字段,值是对应的总和。
答案 2 :(得分:1)
在本机bash中也可以轻松完成此操作。以下代码不使用任何外部工具,没有子shell,也没有管道,因此比您的原始代码 far 更快(我将钱花在典型/合理系统上的吞吐量的100倍上)
declare -A sums=( )
while IFS=, read -r name val; do
sums[$name]=$(( ${sums[$name]:-0} + val ))
done
for key in "${!sums[@]}"; do
printf '%s,%s\n' "$key" "${sums[$key]}"
done
如果愿意,可以将其设置为单线:
declare -A sums=( ); while IFS=, read -r name val; do sums[$name]=$(( ${sums[$name]:-0} + val )); done; for key in "${!sums[@]}"; do printf '%s,%s\n' "$key" "${sums[$key]}"; done