Detect continuous number as range

I have 100k data like this bellow , i want to group data to range

171
172
173
174
175
176
179
182
183
187
188
189
1900
1901
1903
1904
1905
1906
1907

expected output

171 176
179
182 183
187 189
1900 1901
1903 1907

is possible to use awk?

Hello before4,

Not sure how 171 179 is coming as after 176 I couldn't see any thing continuous there. So if that is not the case then following may help you in same.

awk 'NR==1{Q=T=$0}NR>1{if(($0-Q)==1){q=0;} else {if(T==Q){T=$0;Q=$0;next};print T OFS Q;T=$0;Q=$0;next};Q=$0} END{print T OFS Q}' Input_file
 

Output will be as follows.

171 176
182 183
187 189
1900 1901
1903 1907
 

If above code doesn't help you or you have some other conditions in your requirement please get back to us with more precise Input_file and all the conditions and expected sample Output_file too.
EDIT: Changed code above a bit as it was no coming as per OP's expectation.

Thanks,
R. Singh

1 Like

Work perfect, and good finding for my mistake many thanks

RavinderSingh13,
One doubt here , why 179 183 is in your o/p
o/p in the post of before4 does not include it.
Little modification if you want to exclude 179 183

awk 'NR==1{first=$0;prev=$0;next }
$0 - prev == 1 { prev=$0; next } { if (first != prev) { print first,prev;} prev=$0;first=$0 } END { print  first,prev;}' infile

Thanks
Pravin

2 Likes

many thanks Pravin,

Is it possible to print 179 as single line,

171 176
179
182 183
187 189
1900 1901
1903 1907

yes, You can modify code as below.

awk 'NR==1{first=$0;prev=$0;next }
$0 - prev == 1 { prev=$0; next } { if (first != prev) { print first,prev;} else { print prev} prev=$0;first=$0 } END { print  first,prev;}' infile

Thanks Pravin for pointing out the same.

Hello before4,

Apologies for not being perfect previous time. Could you please try following and let me know if this helps you.

awk 'NR==1{Q=T=$0}NR>1{if(($0-Q)==1){q=0;} else {if(T==Q){print Q;T=$0} else {print T OFS Q;T=$0}}};{Q=$0} END{print T OFS Q}'  Input_file

Output will be as follows.

171 176
179
182 183
187 189
1900 1901
1903 1907

EDIT: Also I have edited my previous code too which should give OP's very first expected output.

Thanks,
R. Singh

1 Like

Work perfect, many thanks

root@svr:/var/tmp# more sample.txt 
151442
15144200113571
190370299
2010
212526
212527
212529
212533
212534
212538
212546
212547

root@svr:/var/tmp# awk 'NR==1{Q=T=$0}NR>1{if(($0-Q)==1){q=0;} else {if(T==Q){print Q;T=$0} else {print T OFS Q;T=$0}}};{Q=$0} END{print T OFS Q}'  sample.txt 
151442
15144200113571
190370299
2010
212526 212527
212529
212533 212534
212538
212546 212547

root@svr:/var/tmp# awk 'NR==1{first=$0;prev=$0;next }
> $0 - prev == 1 { prev=$0; next } { if (first != prev) { print first,prev;} else { print prev} prev=$0;first=$0 } END { print  first,prev;}' sample.txt
151442
15144200113571
190370299
2010
212526 212527
212529
212533 212534
212538
212546 212547

Hello before4,

Running my recent code as follows, I am getting as expected result.

awk 'NR==1{Q=T=$0}NR>1{if(($0-Q)==1){q=0;} else {if(T==Q){T=Q=$0;next};print T OFS Q;T=Q=$0;next};Q=$0} END{print T OFS Q}'  Input_file

Output will be as follows.

212526 212527
212533 212534
212546 212547

Please try it and let me know how it goes then.

Thanks,
R. Singh

Hi ,
Try new code from post #6.

Thanks
Pravin

1 Like

Try also

awk '
$1 - prev != 1  {printf "%s%s%s ", first==prev?"":prev, MRS, $1
                 first = $1
                 MRS = RS
                }
                {prev = $1
                }
END             {print prev
                }
' file
1 Like