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

Hi all, I have 2 text files:
1. A.txt 1|||GoRaiders|0473H30DF|123456|Oakland||Test|TD|07/02/2002|01/05/2003| 2|||GoRaiders|019H4151|544419|SpareX||Test|TD|07/02/2002|01/05/2003| 3|||GoRaiders|019H4152|544420|SpareX||Test|TD|07/02/2002|01/05/2003| 4|||GoRaiders||548420|SpareX||Test|TD|07/02/2002|01/05/2003| 5|||GoRaiders||548419|SpareX||Test|Smith|07/02/2002|01/05/2003| 6|||GoRaiders|902F2416|492487|SpareX||Test|TD|08/02/2002|01/20/2003| 7|||GoRaiders|019H4154|544821|SpareX||Test|TD|07/02/2002|01/20/2003| 8|||GoRaiders|924H2CEC|492489|SpareX||Test|TD|07/02/2002|01/20/2003| 2. B.txt 1|TD|01/10/2003|07/11/2003|SpareX|666666||||texas|Yes|Yes|Yes|This is +a test. Please ignore 2|TD|01/10/2003|07/11/2003|SpareX|664464||||newyork|Yes|Yes|Yes|This i +s a test. Please ignore 3|Britney|01/10/2003|07/11/2003|M3|464444|911H3233|||california|Yes|Ye +s|No| 4|TD|01/10/2003|07/11/2003|SpareX|3333333||||texas|Yes|Yes|Yes|This is + a test. Please ignore 5|TD|01/10/2003|07/11/2003|SpareX|4444444||||newyork|Yes|Yes|Yes|This +is a test. Please ignore 6|Britney|01/10/2003|07/11/2003|M3|555555|00000888|||california|Yes|Ye +s|No| 7|TD|01/12/2003|07/11/2003|SpareX|123456||||texas|Yes|Yes|Yes|This is +a test. Please ignore 8|TD|01/12/2003|07/11/2003|SpareX|544419||||newyork|Yes|Yes|Yes|This i +s a test. Please ignore 9|Britney|01/12/2003|07/11/2003|M3|544420|666688855|||california|Yes|Y +es|No|

If today is 01/12/2003 then it will take all the records have today date is 01/12/2003 with expire 07/11/2003 from B.txt with its serial number id, and search in A.txt and check with the serial number in A.txt then replace $addate and $expire.
1|||GoRaiders|0473H30DF|123456|Oakland||Test|TD|01/12/2003|07/11/2003| 2|||GoRaiders|019H4151|544419|SpareX||Test|TD|01/12/2003|07/11/2003| 3|||GoRaiders|019H4152|544420|SpareX||Test|TD|01/12/2003|07/11/2003| 4|||GoRaiders||548420|SpareX||Test|TD|07/02/2002|01/05/2003| 5|||GoRaiders||548419|SpareX||Test|Smith|07/02/2002|01/05/2003| 6|||GoRaiders|902F2416|492487|SpareX||Test|TD|08/02/2002|01/20/2003| 7|||GoRaiders|019H4154|544821|SpareX||Test|TD|07/02/2002|01/20/2003| 8|||GoRaiders|924H2CEC|492489|SpareX||Test|TD|07/02/2002|01/20/2003|

here is my code and it is not working. can you help me to solve it.
#!/usr/bin/perl use strict; use warnings; open FILEB, 'B.txt' or die "B: $!\n"; while (<FILEB>) { my ($id,$add, $expire) = (split /\|/)[5,2,3]; open FILEA, 'A.txt' or die "A: $!\n"; open NEWA, '>A.txt.new' or die "New A: $!\n"; while (<FILEA>) { if (/\|$id\|/) { my @rec = split /\|/; @rec[10, 11] = ($add, $expire): $_ = join ('|', @rec); } print NEWA, $_; } close FILEA; close NEWA: } rename 'A.txt.new', 'A.txt';

Code tags added for data - dvergin 2003-01-12

Replies are listed 'Best First'.
Re: update flat file
by AcidHawk (Vicar) on Jan 13, 2003 at 06:24 UTC

    Firstly, in you code:

    Line 12 ends with a : and should be a ;
    Line 14 must not have a comma after the file handle.. ie print NEWA $_;   }
    Line 16 should be close NEWA; }
    Also close FILEB; should be added.

    Update:

    If today is 01/12/2003 then it will take all the records have today date is 01/12/2003 with expire 07/11/2003 from B.txt

    Nowhere in your code do you test for Todays date..? Enter all the Date::Manip gurus for date matching..;)

    It Also seems that you open and close A and New file A for each line that you read of file B... this seems a little IO heavy does it not.

    -----
    Of all the things I've lost in my life, its my mind I miss the most.
Re: update flat file
by dvergin (Monsignor) on Jan 13, 2003 at 06:28 UTC
    Indenting is a wonderful tool for making it much easier to see what is happening in a piece of code. It is a standard practice among folks who want to get a quick visual grasp of the over-all flow of their code. Here is your program with indenting added:
    #!/usr/bin/perl use strict; use warnings; open FILEB, 'B.txt' or die "B: $!\n"; while (<FILEB>) { my ($id,$add, $expire) = (split /\|/)[5,2,3]; open FILEA, 'A.txt' or die "A: $!\n"; open NEWA, '>A.txt.new' or die "New A: $!\n"; while (<FILEA>) { if (/\|$id\|/) { my @rec = split /\|/; @rec[10, 11] = ($add, $expire): $_ = join ('|', @rec); } print NEWA, $_; } close FILEA; close NEWA: } rename 'A.txt.new', 'A.txt';
    Notice how much more clear the logic of your code becomes when formatted in this way?

    Moving on... you do not describe what result you are getting (beyond saying "it is not working").

    But as you can see, every time through the   while (<FILEB>)   loop you are re-writing a new A.txt.new over the top of the one you wrote on the previous time through the loop. Does that shed any light on the unsatisfactory results you are getting?

    There are other issues with this code and you may soon see a full re-write of your program posted here. But I suspect this is the main issue at this stage in your work.

    UpdateAcidHawk correctly nails several other specific problems. Much of what he calls attention to should have been evident from the error messages produced by your code. Next time, please say more than just "it is not working".

      Hi acidhawk, I really don't know how to get date from B.txt( if they have more than 100 lines..), so i think I will use shell cript to grep today date in add field and dump it in a temp file like B2.txt. Then use this perl program to look for all the $id in B2.txt and search in A.txt then replace adddate and expiredate. I am new and still need to learn from all of you. I found my error in not to use : (mistyping ;). Thanks for your help,
Re: update flat file
by OM_Zen (Scribe) on Jan 13, 2003 at 21:02 UTC
    Hi ,

    , The semicolon is replaced by : . The syntax is not really the ones for perl in places , so you intend and then run the script