如果条件满足,AWK 打印行组两次
AWK print group of lines twice if conditions met
我在编写 AWK 语句时遇到困难,该语句会在指定条件下打印出一组行两次,并可以选择更改重复行中的值。例如,如果一行的第一个字段是 11 ($1=11),那么我想打印出该行和后面的行两次(调整第二列中的值 ($2).
到目前为止,这是我所拥有的,但它不会复制第一个字段 = 到 11 和下一行的行。
awk '{if(NF<3) print [=10=]; if(NF==3 && ==11) print [=10=], 1, 20; if(NF==3 && != 11) print [=10=], 0, 0; if(NF>3) print [=10=];}'
示例输入
1 3
6 0.1 99
0.100 0.110 0.111
7 0.4 88
0.200 0.220 0.222
11 0.5 77
0.300 0.330 0.333
2 2
7 0.3 66
0.400 0.440 0.444
11 0.7 55
0.500 0.550 0.555
这是我想要做的事情的简化版本,所以为了简单起见,我希望打印的 NR 其中 $1==11 和下一行 (NR+1) 在第二行中具有值列 ($2) 是原始值的一半。例如,对于 1 3 部分下的行分组,11 之后的值为 0.5。理想情况下,打印出的行在 11 之后的值为 0.25。
理想输出
1 3
6 0.1 99 0 0
0.100 0.110 0.111
7 0.4 88 0 0
0.200 0.220 0.222
11 0.25 77 1 20
0.300 0.330 0.333
11 0.25 77 1 20
0.300 0.330 0.333
2 2
7 0.3 66 0 0
0.400 0.440 0.444
11 0.35 55 1 20
0.500 0.550 0.555
11 0.35 55 1 20
0.500 0.550 0.555
使用 GNU awk for gensub() 和 \s/\S:
$ awk '==11{[=10=]=gensub(/^(\s+\S+\s+)\S+/,"\1"/2,1); c=2; s=[=10=]} {print} c&&!--c{print s ORS [=10=]}' file
1 3
6 0.1 99
0.100 0.110 0.111
7 0.4 88
0.200 0.220 0.222
11 0.25 77
0.300 0.330 0.333
11 0.25 77
0.300 0.330 0.333
2 2
7 0.3 66
0.400 0.440 0.444
11 0.35 55
0.500 0.550 0.555
11 0.35 55
0.500 0.550 0.555
您可以使用以下 awk 脚本。 (P.S。您的输入文件中有前导和尾随 space。这就是为什么我必须使用 NF>2 && NF<=5 而不是 NF==3。)
BEGIN {
c=0;FS="[ \t]+";OFS=" ";x="";y="";
}
c==2{
print x, 1, 20;
print y;
c=0;
}
NF ==2{
print [=10=];
}
NF>2 && NF<=5{
if(c==1){
print [=10=];
y=[=10=];c=2;next;
}
if(==11){
print [=10=], 1, 20;
x=[=10=];c=1;
}
else print [=10=];
}
NF>5{
print [=10=],"hello";
}
END{
if(c==2){
print x, 1, 20;
print y;
}
}
我在编写 AWK 语句时遇到困难,该语句会在指定条件下打印出一组行两次,并可以选择更改重复行中的值。例如,如果一行的第一个字段是 11 ($1=11),那么我想打印出该行和后面的行两次(调整第二列中的值 ($2).
到目前为止,这是我所拥有的,但它不会复制第一个字段 = 到 11 和下一行的行。
awk '{if(NF<3) print [=10=]; if(NF==3 && ==11) print [=10=], 1, 20; if(NF==3 && != 11) print [=10=], 0, 0; if(NF>3) print [=10=];}'
示例输入
1 3
6 0.1 99
0.100 0.110 0.111
7 0.4 88
0.200 0.220 0.222
11 0.5 77
0.300 0.330 0.333
2 2
7 0.3 66
0.400 0.440 0.444
11 0.7 55
0.500 0.550 0.555
这是我想要做的事情的简化版本,所以为了简单起见,我希望打印的 NR 其中 $1==11 和下一行 (NR+1) 在第二行中具有值列 ($2) 是原始值的一半。例如,对于 1 3 部分下的行分组,11 之后的值为 0.5。理想情况下,打印出的行在 11 之后的值为 0.25。
理想输出
1 3
6 0.1 99 0 0
0.100 0.110 0.111
7 0.4 88 0 0
0.200 0.220 0.222
11 0.25 77 1 20
0.300 0.330 0.333
11 0.25 77 1 20
0.300 0.330 0.333
2 2
7 0.3 66 0 0
0.400 0.440 0.444
11 0.35 55 1 20
0.500 0.550 0.555
11 0.35 55 1 20
0.500 0.550 0.555
使用 GNU awk for gensub() 和 \s/\S:
$ awk '==11{[=10=]=gensub(/^(\s+\S+\s+)\S+/,"\1"/2,1); c=2; s=[=10=]} {print} c&&!--c{print s ORS [=10=]}' file
1 3
6 0.1 99
0.100 0.110 0.111
7 0.4 88
0.200 0.220 0.222
11 0.25 77
0.300 0.330 0.333
11 0.25 77
0.300 0.330 0.333
2 2
7 0.3 66
0.400 0.440 0.444
11 0.35 55
0.500 0.550 0.555
11 0.35 55
0.500 0.550 0.555
您可以使用以下 awk 脚本。 (P.S。您的输入文件中有前导和尾随 space。这就是为什么我必须使用 NF>2 && NF<=5 而不是 NF==3。)
BEGIN {
c=0;FS="[ \t]+";OFS=" ";x="";y="";
}
c==2{
print x, 1, 20;
print y;
c=0;
}
NF ==2{
print [=10=];
}
NF>2 && NF<=5{
if(c==1){
print [=10=];
y=[=10=];c=2;next;
}
if(==11){
print [=10=], 1, 20;
x=[=10=];c=1;
}
else print [=10=];
}
NF>5{
print [=10=],"hello";
}
END{
if(c==2){
print x, 1, 20;
print y;
}
}