Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filling in gaps with awk or anything

Tags:

bash

awk

I have a list such as below, where the 1 column is position and the other columns aren't important for this question.

1  1 2 3 4 5
2  1 2 3 4 5
5  1 2 3 4 5
8  1 2 3 4 5
9  1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5

I want to fill in the gaps such that the list is continuous and it reads

1  1 2 3 4 5
2  1 2 3 4 5
3  0 0 0 0 0
4  0 0 0 0 0 
5  1 2 3 4 5
6  0 0 0 0 0 
7  0 0 0 0 0 
8  1 2 3 4 5
9  1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5

I am familiar with awk and shell scripts, but whatever way it can be done is fine with me. Thanks for any help..

like image 490
jeffpkamp Avatar asked Jul 10 '13 22:07

jeffpkamp


3 Answers

this one-liner may work for you:

awk '$1>++p{for(;p<$1;p++)print p"  0 0 0 0 0"}1' file

with your example:

kent$  echo '1  1 2 3 4 5
2  1 2 3 4 5
5  1 2 3 4 5
8  1 2 3 4 5
9  1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5'|awk '$1>++p{for(;p<$1;p++)print p"  0 0 0 0 0"}1'         
1  1 2 3 4 5
2  1 2 3 4 5
3  0 0 0 0 0
4  0 0 0 0 0
5  1 2 3 4 5
6  0 0 0 0 0
7  0 0 0 0 0
8  1 2 3 4 5
9  1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5
like image 93
Kent Avatar answered Oct 30 '22 09:10

Kent


You can use the following awk one-liner:

awk '{b=a;a=$1;while(a>(b++)+1){print(b+1)," 0 0 0 0 0"}}1' input.file

Tested with here-doc input:

awk '{b=a;a=$1;while(a>(b++)+1){print(b+1)," 0 0 0 0 0"}}1' <<EOF
1  1 2 3 4 5
2  1 2 3 4 5
5  1 2 3 4 5
8  1 2 3 4 5
9  1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5
EOF

the output is as follows:

1  1 2 3 4 5
2  1 2 3 4 5
3  0 0 0 0 0
4  0 0 0 0 0
5  1 2 3 4 5
6  0 0 0 0 0
7  0 0 0 0 0
8  1 2 3 4 5
9  1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5

Explanation:

On every input line b is set to a where a is the value of the first column. Because of the order in which b and a are initialized, b can be used in a while loop that runs as long as b < a-1 and inserts the missing lines, filled up with zeros. The 1 at the end of the script will finally print the input line.

like image 22
hek2mgl Avatar answered Oct 30 '22 08:10

hek2mgl


This is only for fun:

join -a2 FILE <(seq -f "%g 0 0 0 0 0" $(tail -1 FILE | cut -d' ' -f1)) | cut -d' ' -f -6

produces:

1 1 2 3 4 5
2 1 2 3 4 5
3 0 0 0 0 0
4 0 0 0 0 0
5 1 2 3 4 5
6 0 0 0 0 0
7 0 0 0 0 0
8 1 2 3 4 5
9 1 2 3 4 5
10 1 2 3 4 5
11 1 2 3 4 5
like image 1
jm666 Avatar answered Oct 30 '22 10:10

jm666