Search code examples
perlunixawksequential-number

Print the missing number in a unique sequential list with an arbitrary starting range or starting from 1


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.


Solution

  • 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