我有一个具有以下结构的ascii文件:
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,3,0,0,0,0.04,0,0,990,0
1,0,3,0,0,0,0.12,0,0,3760,0
1,0,3,0,0,0,0.21,0,0,5372,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
.
.
.
零代表“随机”数字我不需要照顾。
第3列等于3(总是三个块)我有 使用第7列和第10列执行一些计算:
我需要计算(0.04 * 990)+(0.12 * 3760)+(0.21 * 5372) 并将结果插入所有三行的第5列。 第10列中的值在下一个“三个块”中将有所不同。
以前我用awk做了很多ascii文件编辑,所以如果可能的话我也想在这里使用它。
我的主要问题是在找到第3列= 3后访问接下来的两行,然后再继续搜索两行。
结果应如下所示:
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,3,0,1618.92,0,0.04,0,0,990,0
1,0,3,0,1618.92,0,0.12,0,0,3760,0
1,0,3,0,1618.92,0,0.21,0,0,5372,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
1,0,4,0,0,0,0,0,0,0,0
.
.
.
我希望我能够描述这个问题,如果不是只是问,我会澄清!
我试过了:
awk -F"," '$3 == "3"' in.dat > out.dat
并将其与
结合使用awk -v "n=line numer" -v "s=string to insert" '(NR==n) { print s } 1' input-file
但我的主要问题是我不知道如何在第一行之后访问字段并将其用于公式中进行计算。
我真正需要使用的公式更复杂,但我只是在这里发布了一个简单的例子,因为将它改编为更复杂的解决方案是没有问题的。
答案 0 :(得分:2)
在awk中
awk -F, '$3=="3"{a[++x]=$0;y+=($7*$10)}
!x
x==3{
while(++i<=x){
split(a[i],b,",")
b[5]=y
for(j=1;j<length(b);j++)
c=j>1?c","b[j]:b[j]
print c
c=t
}
x=y=i=0
}' file
a
并将总数添加到变量y
更短,更少资源饥饿的方式(归功于glenn jackmans回答给我的想法)
awk -F, '$3=="3"{a[++x]=$0;y+=($7*$10)}
!x
x==3{
while(++i<=x){
$0=a[i]
$5=y
print
}
i=y=x=0
}' test
答案 1 :(得分:1)
awk的getline
命令可以很好地为你服务
awk -F, -v OFS=, '
$3 == 3 {
c = 0
line1 = $0; c += $7 * $10; getline
line2 = $0; c += $7 * $10; getline
line3 = $0; c += $7 * $10
$0 = line1; $5 = c; print
$0 = line2; $5 = c; print
$0 = line3; $5 = c
}
{print}
'
这对我的口味来说不够干净,但它只有3行并且非常易读。
DRY解决方案
awk -F, -v OFS=, '
$3 == 3 {
c = 0
for(i=1;i<=3;i++)
{line[i] = $0; c += $7 * $10; getline}
for(i=1;i<=3;i++)
{$0 = line[i]; $5 = c; print}
next
}1
'