0

I am trying to find a command that is extracting only the lines that have all their characters in a sequence and in the order as below from a text file.

800900100011001200..(descending by 100) 369121518 (ascending by 3)

Can I do this in one command to print only the lines that have only above orders or have to make one command for every sequence?

3
  • 1
    Is 1245 a sequence? (12, and 45 ascending by 33 or 124 and 5 descending by 119) or does the sequence have to have at least 3 items? Commented Oct 26, 2018 at 14:05
  • @Stephane Chazelas this sequence 369121518.. is ascending by 3 as 3 6 9 12 15 18 ...can you help me with a command that governing that?
    – Ahmed
    Commented Oct 26, 2018 at 15:14
  • @Kusalananda i have tried (?:036|369|6912|912|1215|1218|) but its not working with me and also in this wsy I have to mention all the sequsence in my command i want governining command for that.
    – Ahmed
    Commented Oct 26, 2018 at 15:24

1 Answer 1

3

One approach using perl's (??{...}) experimental regex operator for sequences of 3 or more decimal numbers in linear sequence:

perl -lne 'print if m{^(\d+)(\d+)(?=(.+$))(??{
  my $i = $2; my $r; my $l = length $3; my $incr = $2 - $1;
  while (length($r) < $l) {$i += $incr; $r .= $i}; $r})$}'

Note that it reports on 000000, as that's 0000, 0, 0 or 0, 0, 0, 0, 0, 0 and also on 1023 as that's 1, 02, 3, but the way it works, not on 1203 as the way it works, for the part after the first 2 numbers, it expects a list of numbers without leading 0s.

Similarly, it reports 10-1, but not -101 as a - is not expected in the first two numbers.

You could address that with:

perl -lne 'print if m{^(-?\d+)(-?\d+)(?=(.+$))(??{
  my $i = $2; my $r, $sign, $value; my $m = $3; my $incr = $2 - $1;
  while (($i += $incr),
         (($sign, $value) = ($i =~ /(-?)(\d*)/)),
         $m =~ /^(${sign}0*$value)(.*)/) {
    $r .= $1; $m = $2;
  }; $r})$}'

With which it would report 12000034, -101, -1-2-3, 0-123-246...

6
  • Chazelas its ok thanks but could you please edit it to exclude the last or the last two characters in the line if they are not belong to the sequences above for example print this lines 24685 or 246853.
    – Ahmed
    Commented Oct 26, 2018 at 16:57
  • 1
    For that, you could replace the last $r with $r eq "" ? $r : "$r\\d{0,2}" Commented Oct 26, 2018 at 17:33
  • Dear Stephane Chazelas your commands are ok and worked fine with me..Now I have an equation for descending sequence and ascending sequence and now please I just need an edition for your commad to detect the lines that have both ascending and descending sequence in the same line for example: 246642 or 3698642. And I will be very appreciated.
    – Ahmed
    Commented Oct 26, 2018 at 18:08
  • Chazelas Replacing the last $r with $r eq "" ? $r : "$r\\d{0,2}" is not working correctly with your first perl command.
    – Ahmed
    Commented Oct 26, 2018 at 20:30
  • Chazelas could you please add this exclusion "$r with $r eq "" ? $r : "$r\\d{0,2}" to your first perl command.
    – Ahmed
    Commented Oct 30, 2018 at 11:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .