Saturday, November 9, 2019

bash - AWK print group of lines twice if conditions met




I am having difficulties writing an AWK statement that would print out a group of lines twice under specified conditions, with the option to change values in the lines being repeated. For example, if the first field of a row is 11 ($1=11), then I would like to print out that row and the row that follows twice (adjusting the value in the second column ($2).



So far this is what I have, but it does not replicate lines with the first field = to 11 and the following line.



awk '{if(NF<3) print $0; if(NF==3 && $1==11) print $0, 1, 20; if(NF==3 && $1 != 11) print $0, 0, 0; if(NF>3) print $0;}'


Example Input



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


This is a simplified version of what I would like to do, so let's just say for simplicity I would like the printed NR where $1==11 and following row (NR+1) to have the value in the second column ($2) be half of the original value. Example, for the grouping of rows under the 1 3 section, the value after 11 is 0.5. Ideally, the rows printed out would have the value following 11 to be 0.25.



Ideal Output



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

Answer



With GNU awk for gensub() and \s/\S:



$ awk '$1==11{$0=gensub(/^(\s+\S+\s+)\S+/,"\\1"$2/2,1); c=2; s=$0} {print} c&&!--c{print s ORS $0}' 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

No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...