user1116360
user1116360

Reputation: 422

Convert column pattern

I have this kind of file:

1 0 1

2 0 3
2 1 2

3 0 3

4 0 1
4 1 1
4 2 1
4 3 1

5 0 1



8 0 1


10 0 1

11 0 1

The RS separator is an empty line by default.

If there was a double blank line, we have to substitute on of them by a pattern $1 0 0, where $1 means the increased "number" before the $1 0 * record.

If the separator is empty line + 1 empty line we have to increase the $1 by 1. If the separator is empty line + 2 empty line we have to increase the $1 by 2. ...

and I need to get this output:

1 0 1

2 0 3
2 1 2

3 0 3

4 0 1
4 1 1
4 2 1
4 3 1

5 0 1

6 0 0 

7 0 0

8 0 1

9 0 0

10 0 1

11 0 1

Thanks in advance!

Upvotes: 2

Views: 178

Answers (2)

jaypal singh
jaypal singh

Reputation: 77065

You can try something like this. The benefit of this way is that your input file need not have an empty line for the missing numbers.

awk -v RS="" -v ORS="\n\n" -v OFS="\n" '                   
BEGIN{getline; col=$1;line=$0;print line}
$1==col{print $0;next }
($1==col+1){print $0;col=$1;next}
{x=$1;y=$0; col++; while (col < x) {print col" 0 0";col++};print y;next}' file 

Input File:

[jaypal:~/Temp] cat file
1 0 1

2 0 3
2 1 2

3 0 3

4 0 1
4 1 1
4 2 1
4 3 1

5 0 1



8 0 1


10 0 1

11 0 1

Script Output:

[jaypal:~/Temp] awk -v RS="" -v ORS="\n\n" -v OFS="\n" '                   
BEGIN{getline; col=$1;line=$0;print line}
$1==col{print $0;next }
($1==col+1){print $0;col=$1;next}
{x=$1;y=$0; col++; while (col < x) {print col" 0 0";col++};print y;next}' file
1 0 1

2 0 3
2 1 2

3 0 3

4 0 1
4 1 1
4 2 1
4 3 1

5 0 1

6 0 0

7 0 0

8 0 1

9 0 0

10 0 1

11 0 1

Upvotes: 3

SiegeX
SiegeX

Reputation: 140237

awk 'NF{f=0;n=$1;print;next}f{print ++n " 0 0"}{print;f=1}' ./infile

Output

$ awk 'NF{f=0;n=$1;print;next}f{print ++n " 0 0"}{print;f=1}' ./infile
1 0 1

2 0 3
2 1 2

3 0 3

4 0 1
4 1 1
4 2 1
4 3 1

5 0 1

6 0 0

7 0 0

8 0 1

9 0 0

10 0 1

11 0 1

Explanation

  • NF{f=0;n=$1;print;next}: if the current line has data, unset flag f, save the number in the first field to n, print the line and skip the rest of the script
  • {print;f=1}: We only reach this action if the current line is blank. If so, print the line and set the flag f
  • f{print ++n " 0 0"}: We only execute this action if the flag f is set which only happens if the previous line was blank. If we enter this action, print the missing fields with an incremented n

Upvotes: 4

Related Questions