CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
WORK WITH 2 TO 3 TXT FILES

 



gsvs36
New User

Mar 29, 2009, 12:34 AM

Post #1 of 2 (534 views)
WORK WITH 2 TO 3 TXT FILES Can't Post

 I am a beginer in perl,

please help me.
I have 2 files a.txt b.txt
a.txt like this


5610,MCDOWELL-N,50
5236,JPASSOCIAT,50
5236,KFA,500
5236,MLL,500
5590,DCW,300

b.txt like this

5234,ZEEL,EQ,1000
5236,JPASSOCIAT,EQ,500
5236,SUZLON,EQ,500
5236,ZEEL,EQ,250
5237,MEGH,EQ,15
5970,IBSEC,EQ,100
5970,SYNDIBANK,EQ,100
5970,VISHALEXPO,EQ,35000

In the out put i want
1.match $a2,$b2 next if $a1 and $a2 same then total $a3+$b4
2.all from a.txt except above match
3.all from b.txt except above match

like this

5610,MCDOWELL-N,50
5236,JPASSOCIAT,550
5236,KFA,500
5236,MLL,500
5590,DCW,300
5234,ZEEL,EQ,1000
5236,SUZLON,EQ,500
5236,ZEEL,EQ,250
5237,MEGH,EQ,15
5970,IBSEC,EQ,100
5970,SYNDIBANK,EQ,100
5970,VISHALEXPO,EQ,35000

my code is

#!/usr/bin/perl -w
open (A,"<a.txt");
open (B,"<b.txt");

while (<A>){
chomp;
($a1,$a2,$a3)=split(/,/);
seek B,0,0;
while (<B>){
chomp;
($b1,$b2,$b3,$b4)=split(/,/);

if ($a2 eq $b2){
print "$a1,$a2,$a3\n";
if ($a1 eq $b1){

$q= ($a3+$b4);
print "$a1,$a2,$q\n";
}}}}
close A;
close B;

but it not giving correct one .please help me


1arryb
User

Mar 30, 2009, 3:45 PM

Post #2 of 2 (516 views)
Re: [gsvs36] WORK WITH 2 TO 3 TXT FILES [In reply to] Can't Post

Hi gsvs36,

In future postings, please help us out by indenting your code.

You are completely rescanning b.txt for every line of a.txt. This is very inefficient.

If b.txt is small enough to load into memory, load it into a hash before stepping through a.txt
(see below for one possible implementation).

If b.txt is very large, maybe a.txt isn't. This approach could still work if you invert the logic
(cache a.txt and iterate over b.txt). With modern computers, it's rare that both files will be
so large that the smaller of them can't be loaded.

HOWEVER, it does happen. If both files are too large to load into a hash, you'll have (at least) 3 choices:

1. Segment the problem (ie., load the first n lines of b.txt, iterate, load the next n lines of b.txt, repeat); or

2. Pre-sort a.txt and b.txt and step through both files at the same time, matching values as you go.

3. Something fancy suggested by FishMonger maybe using the Tie module :)

Good luck,

Larry


Code
#!/usr/bin/perl 

use strict;
use warnings;

my $afile = $ARGV[0];
my $bfile = $ARGV[1];

die "usage: $0 <afile> <bfile>" unless $afile and $bfile;

open (A, "<$afile") or die "Can't open $afile for reading";
open (B, "<$bfile") or die "Can't open $bfile for reading";

my $bhash = {}; # This is a reference to a hash.
while (my $line = <B>)) {
$line =~ tr/\r\n//d; # Like chomp().
my ($b1, $b2, $b3, $b4) = split(/,/, $line);
$bhash->{$b2}->{$b1} = $b4;
}
close B;

while (my $line = <A>) {
$line =~ tr/\r\n//d;
my ($a1, $a2, $a3) = split(/,/, $line);
if ( exists($bhash->{$a2}) ) {
# This is a transliteration of your original logic.
# Note that it outputs two records per a.txt line if $a1 eq $b1.
print "$line\n";
if ( exists($bhash->{$a2}->{$a1}) ){
my $q = ( $a3 + $bhash->{$a2}->{$a1} );
print "$a1,$a2,$q\n";
}
}
}
close A;


If you run this code, you get:

Code
5236,JPASSOCIAT,50 
5236,JPASSOCIAT,550


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives