Hi,

I would like to the code below to search the contents of file1 in file2 and then output results arranged according to file1 contents. At the moment the code outputs are according to the order of elemnts in file2. I need some help to get this code working as expected.

File 1:

Xm36378merp_ax
sm3722bsb223_am
S23p1234mxm_am
xxx56sssssxxm_au

File 2:

S23p1234mxm_am sjtu
Xm36378merp_ax mxth
sc373939bnss_at mmsx
we223n23g23w_aj jutx
sm3722bsb223_am sdcnm

Output

Xm36378merp_ax mxth
sm3722bsb223_am sdcnm
S23p1234mxm_am sjtu
xxx56sssssxxm_au Nothing found

working code:

use warnings;
use strict;
my $time = scalar localtime(); # get date of search
my $heading = <<"HOF";
Date of search: $time
The Following Matches were Found in File 1:
HOF

my $heading = qq(Date of search: $time\nThe Following Matches were Found in File 1:\n);
my %hash;
my $file1 = 'File1.txt'; # file1: one column of probe names for searching the second file.
open my $fh, '<', $file1 or die "can't open $file1:$!";
while (<$fh>) {
chomp;
undef $hash{$_};
}
close $fh;
my $file2 = 'File2.txtt'; # file 2: file with two columns to be searched with contents of file1.
open my $fh_new, '>', 'outFile.txt' or die "can't open file:$!"; # output file
open $fh, '<', $file2 or die "can't open this file:$!";
print $fh_new $heading;
while ( defined( my $line = <$fh> ) ) {
chomp $line;
my $checked_word;
if ( $line =~ m/(.+?)\s+?.+?$/ ) {
$checked_word = $1;
exists $hash{$checked_word}
? print $fh_new $line, $/
: print $fh_new $checked_word, " No Match Found", $/;
}
}
close $fh or die "can't close file:$!";
close $fh_new or die "can't close file:$!";

Thanks for your help

Recommended Answers

All 6 Replies

open my $fh, '<', $file1 or die "can't open $file1:$!";

Why do you have statements like the above where I see '&lt;' instead of '<'? Besides fixing the above, mostly all you need to do to get what you want is to switch the filenames, as follows:

#!/usr/bin/perl
use warnings;
use strict;
my $time = scalar localtime();    # get date of search

#Heading should say 'File 2', not 'File 1'
my $heading =
  qq(Date of search: $time\nThe Following Matches were Found in File 2:\n);
my %hash;

#Save the file you want to search ($file2, not $file1, into %hash)
my $file2 = 'File2.txt';    # file 2: file with two columns to be searched with contents of file1.
open my $fh, '<', $file2 or die "can't open $file2:$!";
while (<$fh>) {
    chomp;
    my ($probe, $value) = split /\s+/, $_;
    $hash{$probe} = $value;
}
close $fh;

my $file1 =
  'File1.txt'; # file1: one column of probe names for searching the second file.
open my $fh_new, '>', 'outFile.txt' or die "can't open file:$!";   # output file
open $fh, '<', $file1 or die "can't open this file:$!"; # ($file1, not $file2)
print $fh_new $heading;
while ( defined( my $line = <$fh> ) ) {
    chomp $line;
    my $checked_word;
    if ( $line ) {
        $checked_word = $line;
        exists $hash{$checked_word}
          ? print $fh_new $checked_word, ' ', $hash{$checked_word}, $/
          : print $fh_new $checked_word, " No Match Found", $/;
    }
}
close $fh     or die "can't close file:$!";
close $fh_new or die "can't close file:$!";

Nice one d5e5, I was going to point out your initial statement of just switching the last solution posted, the other time. It works fine!

However, I decided to add and remove a little to see how another solution looks. Ofcourse, are we not talking Perl? Believe me it fun all the way.

Perly, you can also try this one below:
It works fine too!

#!/usr/bin/perl
use warnings;
use strict;

my $matched_word_ref = {};
my $file2            = 'file2.txt';

open my $fh, '<', $file2 or die "can't open file:$!";
while ( defined( my $line = <$fh> ) ) {
    chomp $line;
    if ( $line =~ m/(.+?)\s+?(.+?)$/ ) {
        $matched_word_ref->{$1} = $2;
    }
}
close $fh or die "can't close file:$!";

my $file1 = 'file1.txt';
my $timer = scalar localtime();

open my $fh_new, '>', 'output.txt' or die "can't open file:$!";    # output file
print $fh_new qq{Date of search: $timer
 The Following Matches were Found in File 1:\n};

open $fh, '<', $file1 or die "can't open file:$!";
while ( defined( my $word = <$fh> ) ) {
    chomp $word;
    if ( exists $matched_word_ref->{$word} ) {
        print $fh_new $word, q{ }, $matched_word_ref->{$word}, $/;
    }
    else { print $fh_new $word, " Nothing Found", $/; }
}
close $fh     or die "can't close file:$!";
close $fh_new or die "can't close file:$!";

Hope you fine this helpful.

Once again, thanks to the two of you for bailing me out. The two scripts worked beautifully. Was "$/" in lines the scripts (32 and 33 - d5e5) and lines (28 and 30 - 2teez) used as a dereference and why? I have not been able to find the explanation for it's use anywhere.

Apologies! '&lt; was a carry-over from my textpad.

Was "$/" in lines the scripts (32 and 33 - d5e5) and lines (28 and 30 - 2teez) used as a dereference and why?

No. I copied the lines where "$/" occurs from 2teez' scripts. By default the Perl special variable has a value of "\n" and, since our scripts don't modify it, we could have put "\n" instead and achieved the same result.

$/
The input record separator, newline by default. This influences Perl's idea of what a "line" is.
from perldoc perlvar

commented: Nice one!!! +2

Once again, thanks to the two of you for bailing me out. The two scripts worked beautifully. Was "$/" in lines the scripts (32 and 33 - d5e5) and lines (28 and 30 - 2teez) used as a dereference and why? I have not been able to find the explanation for it's use anywhere.

Apologies! '&lt; was a carry-over from my textpad.

I've ceretainly gained more perl knowledge, thanks to you guys! Best wishes.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.