emadmahou has asked for the wisdom of the Perl Monks concerning the following question:

I have too files the first file will have 31 integer

  • 0026110795165557564528452972062
  • 0026110795165557648628452974959
  • 0026110795182749420290503162401
  • 0026110795182749566690703875348
  • 0026110795182750564290503365856
  • 0026110795182751155490713282618
  • 0026110795182751819190503415474
  • 0026110795182752054790503331977
  • 0026110795182752888194578410931
  • 0026110795182753115893308242647
  • 0026110795182753522398248322033
  • 0026110795182753601890723246006
  • 0026110795182754156995403760702
  • 0026110795182754174597213102232
  • 0026110795182754408698248770395
  • 0026110795182754919290713221614
  • 0026110795182755128698248922635
  • 0026110795182755566790713334451
  • 0026110795182755669490713213633
  • 0026110795182755806390507009696
  • 0026110795182756204890713212248
  • 0026110795182756217690713273839
  • 0026110795182756259998248961157
  • 0026110795182756309595403769515
  • 0026110795182756708894578164887
  • 0026110795182756829090713282238
  • 0026110795182757082791367220156
  • 0026110795182757130090713274108
  • 0026110795182757297798248934527
  • 0026110795182757370277063564556
  • the second file will have this

  • imb,version ,655575645,827544086
  • imb,versionb ,827549192,827573702
  • the ranges in the sond file is generated from the first file which is located in position 11 for 9 char

    I am so new for perl I need help creating a code that will open the first file and chop off the numbers in position 11 for 9 char then compare these numbers to the range in the second file, then print the original number before being chopped off and print the second part of the file 2 "version OR versionb" Thank you guys

    • Comment on Comparing two files one with numebers and the other one with ranges range and printing matches

    Replies are listed 'Best First'.
    Re: Comparing two files one with numebers and the other one with ranges range and printing matches
    by choroba (Cardinal) on Jun 12, 2015 at 22:43 UTC
      I stored the ranges in an array. If the number of the ranges was large, I'd probably sort them and use binary search to locate the matching one(s).
      #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; open my $F2, '<', 'file2' or die $!; my @ranges; while (<$F2>) { chomp; my ($version, $from, $to) = (split /,/)[ 1, 2, 3 ]; push @ranges, [ $from, $to, $version ]; } open my $F1, '<', 'file1' or die $!; while (<$F1>) { chomp; my $n = substr $_, 11, 9; my $printed; for my $r (@ranges) { if ($r->[0] <= $n && $n <= $r->[1]) { say "$_,$r->[2]"; $printed = 1; } } say "$_, no match" unless $printed; }
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        It worked perfectly

        Can you just explain to me what did you do please

        Thank you so much :),/p>

          The script first opens the second file and reads the ranges into an array of arrays. Then, it reads the first file line by line, extracts the number from the given position, and iterates over all the ranges to find the matching one(s). If it finds them, it prints the desired output, if not, it prints "no match".
          لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
    Re: Comparing two files one with numebers and the other one with ranges range and printing matches
    by CountZero (Bishop) on Jun 13, 2015 at 08:21 UTC
      With the help of the Number::Range module it becomes short and easy:
      use Modern::Perl q/2015/; use Number::Range; # First we make the range objects my $version = Number::Range->new("655575645..827544086"); my $versionb = Number::Range->new("827549192..827573702"); # Then we run our data through these ranges while (<DATA>) { chomp; my $int = substr( $_, -9 ); # take last 9 chars only say "$_ version" if $version->inrange($int); say "$_ versionb" if $versionb->inrange($int); } __DATA__ 0026110795165557564528452972062 0026110795165557648628452974959 0026110795182749420290503162401 0026110795182749566690703875348 0026110795182750564290503365856 0026110795182751155490713282618 0026110795182751819190503415474 0026110795182752054790503331977 0026110795182752888194578410931 0026110795182753115893308242647 0026110795182753522398248322033 0026110795182753601890723246006 0026110795182754156995403760702 0026110795182754174597213102232 0026110795182754408698248770395 0026110795182754919290713221614 0026110795182755128698248922635 0026110795182755566790713334451 0026110795182755669490713213633 0026110795182755806390507009696 0026110795182756204890713212248 0026110795182756217690713273839 0026110795182756259998248961157 0026110795182756309595403769515 0026110795182756708894578164887 0026110795182756829090713282238 0026110795182757082791367220156 0026110795182757130090713274108 0026110795182757297798248934527 0026110795182757370277063564556
      Output:
      0026110795182749566690703875348 version 0026110795182751155490713282618 version 0026110795182753601890723246006 version 0026110795182754919290713221614 version 0026110795182755566790713334451 version 0026110795182755669490713213633 version 0026110795182756204890713212248 version 0026110795182756217690713273839 version 0026110795182756829090713282238 version 0026110795182757130090713274108 version

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      My blog: Imperial Deltronics
        #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; unlink $outputfile; unlink $outputfile2; unlink $outputfile3; sub trimspaces { my @argsarray = @_; $argsarray[0] =~ s/^\s+//; $argsarray[0] =~ s/\s+$//; return $argsarray[0]; } open(INPUT , "< D:\\Home\\test\\imbfilelist.txt") or die $!; open(INPUT2 , "< D:\\Home\\test\\imbrange.txt") or die $!; my $n; my $value; my @ranges; my $isMatch; my $printed; my $fVersion; my %versionHash=(); while (<INPUT2>) { chomp; my ($version, $from, $to) = (split /,/)[ 1, 2, 3 ]; push @ranges, [ $from, $to, trimspaces($version)]; if (!exists $versionHash{trimspaces($version)}) { $versionHash{trimspaces($version)}=0; } } $versionHash{"No Matched"}=0; # foreach my $key (keys %fileHandleHash) # { # close $fileHandleHash{$fVersion}; # } close INPUT2; while (<INPUT>) { $isMatch=0; $n = substr($_,12-1,9); for my $r (@ranges) { if ( $n >= $r->[0] && $n <= $r->[1]) { $fVersion=$r->[2]; if (exists $versionHash{$fVersion}) { $versionHash{$fVersion}++; } $isMatch=1; last; } } if (!$isMatch) { $versionHash{"No Matched"}++; } } foreach my $key (keys %versionHash) { print STDOUT "$key IMB Count: " . $versionHash{$key} . "\n"; } close INPUT;
        I have change the code to loop throw my output looks like this folded IMB Count: 15 No Matched IMB Count: 1 selfmail IMB Count: 14 I now need to be able to create files for each instance: first file will be folded.txt with 15 of the original number seconde file will be nomatch.txt with the original as well and same for the third. any advice??
          I'm quite sure it is possible, but you will first have to explain the rules how to differentiate between these three categories.

          CountZero

          A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

          My blog: Imperial Deltronics
    Re: Comparing two files one with numebers and the other one with ranges range and printing matches
    by GotToBTru (Prior) on Jun 12, 2015 at 21:58 UTC

      What do you have so far? If you don't know where to start, the tutorial section here or tutorials on the web are a good place to start.

      Dum Spiro Spero