我需要以下帮助,我有这些记录:
2 8 [4] 2 2 5 8 4 5 6 1
3 4 1 2 4 8 9
我应该添加突出显示的列,并打印出总和和平均值。
因此,如果记录包含“[]” - s,我们应该在此字符+ 1之后开始求和形式,否则从第4列开始到结束。
我希望这个输出:
2 8 [4] 2 2 5 8 4 5 6 1 31 4.4285
3 4 1 2 4 8 9 23 5.75
提前致谢!
答案 0 :(得分:3)
一种方式:
script.awk 的内容:
{
## If exists in the line any number surrounded with square brackets...
if ( $0 ~ /\[[0-9]+\]/ ) {
## Find its position (beginning the search from the end because I
## want the last one, and begin the count position two numbers later.
for ( i = NF; i >= 1; i-- ) {
if ( $i ~ /^\[[0-9]+\]$/ ) {
pos = i + 2
break
}
}
} else {
## Default position when not found any square brackets.
pos = 4
}
## Sum numbers and count them from the position set before until last number.
for ( j = pos; j <= NF; j++ ) {
sum += $j
count++
}
## Print to output.
printf "%s %.5g %.5g\n", $0, sum, (sum / count)
sum = 0
count = 0
pos = 0
}
infile的内容:
2 8 [4] 2 2 5 8 4 5 6 1
3 4 1 2 4 8 9
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1
运行脚本:
awk -f script.awk infile
结果:
2 8 [4] 2 2 5 8 4 5 6 1 31 4.42857
3 4 1 2 4 8 9 23 5.75
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1 70 5.8333
答案 1 :(得分:1)
awk oneliner可以解决这个问题:
awk -F'] ' '{s=$NF; sum=0;avg=0;split(s,n," "); idx=NF>1?2:4;for(x=idx;x<=length(n);x++)sum+=n[x]; avg=sum/(length(n)-idx+1); print $0" "sum" "avg;} inputFile
试验:
kent$ cat v
2 8 [4] 2 2 5 8 4 5 6 1
3 4 1 2 4 8 9
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1
kent$ awk -F'] ' '{s=$NF; sum=0;avg=0;split(s,n," "); idx=NF>1?2:4;for(x=idx;x<=length(n);x++)sum+=n[x]; avg=sum/(length(n)-idx+1); print $0" "sum" "avg;} ' v
2 8 [4] 2 2 5 8 4 5 6 1 31 4.42857
3 4 1 2 4 8 9 23 5.75
1 15 [4] [8] [12] 4 1 4 8 3 7 9 4 8 9 7 9 1 70 5.83333
答案 2 :(得分:0)
这可能是sed / bash解决方案适合您:
sum(){ { printf "a+=%d;" $@; echo "scale=4; a"; } | bc -l; }
avg(){ { printf "a+=%d;" $@; echo "scale=4; a/$#"; } | bc -l; }
set -f sum avg
sed 's/^.*]\s*\S*\s*\(.*\)/& $(sum \1) $(avg \1)/;ta;s/^\(\s*\S*\)\{3\}\s*\(.*\)/& $(sum \2) $(avg \2)/;:a;s/.*/echo "&"/' file | sh