2

I have two files. File ci.text has list of numbers and file search.text is regular file (log file kind). I want search each number present in file ci.text exist in file search.text or not? I tried following program but vain.

open(my $ci,"<","ci.text") or die $!;
open(my $si,"<","search.text") or die $!;
while (<$ci>) {
    print $_;
    if ( grep /$_/, $si )
    {
       print " not found ---$_ \n";
    }else
    {
       print "found ---$_ \n";
    }
}
2
  • Are the numbers integers one on each lines ? Commented Jan 6, 2015 at 4:22
  • yes. those are integers (like 789-32, 456-12) Commented Jan 6, 2015 at 4:29

3 Answers 3

2

You can't grep a file handle, unless you use File::Grep. You could also hand this task off to your shell with a system call, but I will presume you want a pure perl solution.

perl grep works best against an array, so if you wanted to use grep you would load the whole file into an array, then grep each line against it, eg.

my @si = <$si>;
while (<$ci>) {
    my $found = grep {/$_/} @si;
    print ($found ? "FOUND: $_" : "NOT FOUND: $_");
}

That print uses a ternary operator which - if your not familiar - is just a terse if/else statement.

If the "search" file is exceedingly large, loading the whole thing into an array (ie. into memory) may not be advisable, in which case you might want to nest your while's

OUTER:
while (my $num = <$ci>) {
    while (<$si>) {
        if (/$num/) {
            print "FOUND: $num";
            next OUTER;
        }
    }
    print "NOT FOUND: $num"
}

NB. I don't have your files in your format, so I can't test this code.

Sign up to request clarification or add additional context in comments.

Comments

2

What I would do :

#!/usr/bin/env perl

use strict; use warnings;
use List::MoreUtils qw/any/;

open(my $ci, "<", "ci.text") or die $!;
open(my $si, "<", "search.text") or die $!;

chomp(my @si_arr = <$si>);
chomp(my @ci_arr = <$ci>);

close $si;
close $ci;

foreach my $c (@ci_arr) {
    if (any {$_ eq $c} @si_arr) {
        print "found $c \n";
    }
    else {
        print "not found $c \n";
    }
}

OUTPUT:

found 0 
found 1 
...
found 18 
found 19 
found 20 
not found 21 
not found 22 
not found 23 

Or searching only intersection :

#!/usr/bin/env perl

use strict; use warnings;
use List::Compare;

open(my $ci, "<", "ci.text") or die $!;
open(my $si, "<", "search.text") or die $!;

chomp(my @si_arr = <$si>);
chomp(my @ci_arr = <$ci>);

my $w = List::Compare->new(\@si_arr, \@ci_arr);
print join "\n", sort { $a <=> $b }  @{ $w->{intersection} }

Comments

1

You may use File::Grep

File::Grep mimics the functionality of the grep function in perl, but applying it to files instead of a list. This is similar in nature to the UNIX grep command, but more powerful as the pattern can be any legal perl function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.