带awk的行和,后面跟着一个变换

  • 本文关键字:变换 一个 awk awk
  • 更新时间 :
  • 英文 :


我有这个:

.2 .5
.1 .1
.3 .3

我想要两列结果:

一列表示每行的总和

1的第二列-当总和大于.5 时,每行的总和

.7 .3
.2 .2
.6 .4

我知道如何获得行和列:

awk '{for(i=1;i<=NF;i++) t+=$i; print t; t=0}'

不知道如何获得第二列(如果可能的话,在同一个awk一行(

非常感谢任何建议,谢谢!

如果只有两列,可以先对这两列求和。对于第二列,如果总和本身大于0.5,则打印1-sum。

否则你就打印总数。

awk '{
sum = $1 + $2
print sum, (sum > 0.5 ? 1 - sum : sum)
}' file

输出

0.7 0.3
0.2 0.2
0.6 0.4

如果您想删除前导零,您可以将gnu-awk与gensub一起使用,并使用正则表达式和2个捕获组捕获FS和可选减号:

awk '{
sum = $1 + $2
print gensub(/(^|[[:space:]]+)(-?)0+/,
"\1\2",
"g",
sum FS (sum > 0.5 ? 1 - sum : sum))
}' file

输出

.7 .3
.2 .2
.6 .4

向输入文件添加几行:

$ cat file
.2 .5
.1 .1
.3 .3
11.3 .3
1.3 .3

awk的一个想法是使用条件(也称为三元(表达式来确定第二个输出列:

$ awk '{t=0; for(i=1;i<=NF;i++) t+=$i; print t, (t>0.5 ? 1-t : t)}' file
0.7 0.3
0.2 0.2
0.6 0.4
11.6 -10.6
1.6 -0.6

如果前面的0需要删除,有一个暴力的想法:

$ awk '{ t=0;
for(i=1;i<=NF;i++) t+=$i
out=t OFS (t>.5 ? 1-t : t) 
gsub(/^0./,".",out)
gsub(/-0./,"-.",out)
gsub(/ 0./," .",out) 
print out
}' file
.7 .3
.2 .2
.6 .4
11.6 -10.6
1.6 -.6

或者,如果您有GNU awk(用于<字边界标志(:

$ awk '{ t=0;
for(i=1;i<=NF;i++) t+=$i
out=t OFS (t>.5 ? 1-t : t)
gsub(/<0./,".",out)
print out
}' file
.7 .3
.2 .2
.6 .4
11.6 -10.6
1.6 -.6

或者,如果您不介意生成子流程。。。添加karakfa的sed建议:

$ awk '{t=0; for(i=1;i<=NF;i++) t+=$i; print t, (t>0.5 ? 1-t : t)}' file | sed 's/b0././g'
.7 .3
.2 .2
.6 .4
11.6 -10.6
1.6 -.6
{m,g,n}awk 'BEGIN { OFMT = "%."(_^=_<_) "f" (__="")
____ = "["(___=".") "]"
} ($NF = (($_ += $NF) + $_)<_ ? $_ : _-$_)^__^gsub((!_)____, ___)'

最新更新