我有一个包含4列的文件,例如:
A B C D
1 2 3 4
10 20 30 40
100 200 300 400
.
.
.
我可以计算列B到D与A的梯度,例如以下命令:
NR>1{print $0,($2-b)/($1-a)}{a=$1;b=$2}' file
如何打印渐变之和作为文件中的第5列?结果应该是:
A B C D sum
1 2 3 4 1+2+3+4=10
10 20 30 40 (20-2)/(10-1)+(30-3)/(10-1)+(40-4)/(10-1)=9
100 200 300 400 (200-20)/(100-10)+(300-30)/(100-10)+(400-40)/(100-10)=9
.
.
.
答案 0 :(得分:1)
awk 'NR == 1 { print $0, "sum"; next } { if (NR == 2) { sum = $1 + $2 + $3 + $4 } else { t = $1 - a; sum = ($2 - b) / t + ($3 - c) / t + ($4 - d) / t } print $0, sum; a = $1; b = $2; c = $3; d = $4 }' file
输出:
A B C D sum
1 2 3 4 10
10 20 30 40 9
100 200 300 400 9
使用... | column -t
:
A B C D sum
1 2 3 4 10
10 20 30 40 9
100 200 300 400 9
更新
#!/usr/bin/awk -f
NR == 1 {
print $0, "sum"
next
}
{
sum = 0
if (NR == 2) {
for (i = 1; i <= NF; ++i)
sum += $i
} else {
t = $1 - a[1]
for (i = 2; i <= NF; ++i)
sum += ($i - a[i]) / t
}
print $0, sum
for (i = 1; i <= NF; ++i)
a[i] = $i
}
用法:
awk -f script.awk file
答案 1 :(得分:1)
如果对第一行数字应用与第二行相同的逻辑,将每列的初始值设为0,则得到9作为总和的结果(原来在你的问题中) 。该方法使用循环来累积从第二个字段到最后一个字段的梯度之和。它使用的事实是,在第一轮中,数组a
中未初始化的值计算为0:
awk 'NR==1 { print $0, "sum"; next }
{
s = 0
for(i=2;i<=NF;++i) s += ($i-a[i])/($1-a[1]) # accumulate sum
for(i=1;i<=NF;++i) a[i] = $i # fill array to be used for next iteration
print $0, s
}' file
如果需要,可以将它们全部打包到一行,但记得用分号分隔语句。仅使用for
循环if
时,它也会略短一些:
awk 'NR==1{print$0,"sum";next}{s=0;for(i=1;i<=NF;++i)if(i>1)s+=($i-a[i])/($1-a[1]);a[i]=$i;print$0,s}' file
输出:
A B C D sum
1 2 3 4 9
10 20 30 40 9
100 200 300 400 9