Home > Software design >  Print the missing number in a unique sequential list with an arbitrary starting range or starting fr
Print the missing number in a unique sequential list with an arbitrary starting range or starting fr

Time:04-28

This question is similar to How can I find the missing integers in a unique and sequential list (one per line) in a unix terminal?.

The difference being is that I want to know if it is possible to specify a starting range to the list

I have noted the following provided solutions:

awk '{for(i=p 1; i<$1; i ) print i} {p=$1}' file1

and

perl -nE 'say for $a 1 .. $_-1; $a=$_'

file1 is as below:

5
6
7
8
15
16
17
20

Running both solutions, it gives the following output:

1
2
3
4
9
10
11
12
13
14
18
19

Note that the output start printing from 1.

Question is how to pass an arbitrary starting/minimum to start with and if nothing is provided, assume the number 1 as the starting/minimum number?

9
10
11
12
13
14
18
19

Yes, sometimes you will want the starting number to be 1 but sometimes you will want the starting number as the least number from the list.

CodePudding user response:

Slight variations of those one-liners to include a start point:

awk

# Optionally include start=NN before the first filename
$ awk 'BEGIN { start= 1 }
       $1 < start { next }
       $1 == start { p = start }
       { for (i = p   1; i < $1; i  ) print i; p = $1}' start=5 file1
9
10
11
12
13
14
18
19
$ awk 'BEGIN { start= 1 }
       $1 < start { next }
       $1 == start { p = start }
       { for (i = p   1; i < $1; i  ) print i; p = $1}' file1
1
2
3
4
9
10
11
12
13
14
18
19

perl

# Optionally include -start=NN before the first file and after the --
$ perl -snE 'BEGIN { $start //= 1 }
             if ($_ < $start) { next }
             if ($_ == $start) { $a = $start }
             say for $a 1 .. $_-1; $a=$_' -- -start=5 file1
9
10
11
12
13
14
18
19
$ perl -snE 'BEGIN { $start //= 1 }
             if ($_ < $start) { next }
             if ($_ == $start) { $a = $start }
             say for $a 1 .. $_-1; $a=$_' -- file1
1
2
3
4
9
10
11
12
13
14
18
19

CodePudding user response:

You can use your awk script, slightly modified, and pass it an initial p value with the -v option:

$ awk 'BEGIN{p=p?p:1} {for(i=p; i<$1; i  ) print i} {p=p<=$1?$1 1:p}' file1
1
2
3
4
9
10
11
12
13
14
18
19
$ awk -vp=10 'BEGIN{p=p?p:1} {for(i=p; i<$1; i  ) print i} {p=p<=$1?$1 1:p}' file1
10
11
12
13
14
18
19

The BEGIN block initializes p to 1 if it is not specified. The loop starts at p instead of p 1, and the last block assigns $1 1 to p (instead of $1), if and only if p is less or equal $1.

  • Related