Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Adding duplicate rows to existing records

Status
Not open for further replies.

hello99hello

Programmer
Jul 29, 2004
50
CA
I have an input file (pers_in.txt) with the following records:
2067,Janice,LIFE,Y -------record 1
2067,Janice,MSP,Y -------record 2
2045,Enry,LIFE,Y -------record 3
2045,Enry,OPT,N -------record 4
2345, Louis,MSP,N -------record 5
2345, Louis,OPT,N -------record 6

My purpose is to put it in array, manipulate each record and generate ouput file.

Here is my effort:

#check input file
$input_file = "pers_in.txt";
(-e $input_file) || die ("input file does not exist \n") ;
open(INPUT, "$input_file") || die ("could not open infile\n");
open(OUTPUT, ">$output_file") || die ("could not open outfile \n") ;
@array_file = <INPUT> ;
foreach $array_record (@array_file){
@array = split (",", $array_record) ;

#if there is 'Y' in the fourth element, insert duplicate record only once for each first element (once for 2067 and once for 2045) let us call this record 1d.
#lastly change the values of the second and third element of only the newly added record from Janice to Janice2 and LIFE to EHP LIFE while leaving other elements the same .
# can this be done in perl or it would be eaiser in SQL?

if ($array[3] = "Y"){

#Here is where I am stumped, any help would be really appreciated.

}
}

#print the output
$new_record = join ',', @array;
print OUTPUT "$new_record\n";
}
close (INPUT) ;
close (OUTPUT) ;

The sample output record file could look like:
2067,Janice,LIFE,Y -------record 1
2067,Janice2,EHP LIFE,Y -------record 1d
2067,Janice,MSP,Y -------record 2
2045,Enry,LIFE,Y -------record 3
2045,Enry2, EHP LIFE,Y -------record 3d
2045,Enry,OPT,N -------record 4
2345, Louis,MSP,N -------record 5
2345, Louis,OPT,N -------record 6
 
Try this:
Code:
my @inArray, @outArray ;
open(IN, '<yourfile.txt') ;
@inArray = <IN> ;
close(IN) ;

foreach my $tmpLine (@inArray) {
    my ($id, $name, $att, $yesno) = ($tmpLine =~ m!(.+),(.+),(.+),(Y|N)!i) ;

    push(@outArray, $tmpLine) ;

    if ($yesno eq "Y") {
        push(@outArray, sprintf("%s,%s,%s,Y", ($id, $name . '2', ($att eq 'LIFE' ? 'EHP LIFE' : $att)))) ;
    }
}

open(OUT, '>youroutputfile.txt') ;
print OUT @outArray ;
close(OUT) ;

I supposed that the '-------record X' at the end were only there to indicate us which line you were talking about... if they really are in the file... it won't work properly.

Tell me if it works.
 
Thanx for your reply. However it did not work.

Here is the sample input line:
200069,Y,03/05/1990
209867,N,03/07/1991

The object is to duplicate the above line in the output file, each time the second element is "Y". Also, to convert the date to format dd-mm-yy

Here is the code I used:

#!/usr/bin/perl
use strict ;
#use warnings ;
use Date::Manip ;

my (@inArray, @outArray) ;
open(IN, '<benpen_in.txt') ;
@inArray = <IN> ;
close(IN) ;

foreach my $tmpLine (@inArray) {
$date = ParseDate("$array[2]") ;
$array[16] = UnixDate($date, "%e-%b-%Y\n") ;
my ($id, $yesno, $date) = ($tmpLine =~ m!(.+),(Y|N)!i,(.+)) ;

push(@outArray, $tmpLine) ;

if ($yesno eq "Y") {
#push(@outArray, sprintf("%s,%s,%s,Y", ($id, $name . '2', ($att eq 'LIFE' ? 'EHP LIFE' : $att)))) ;
push(@outArray, sprintf("%s,Y,%s", ($id,$date))) ;
}
}

open(OUT, '>benpen_out.txt') ;
print OUT @outArray ;
close(OUT) ;

My sample ouput file should be:
200069,Y,03-May-1990
200069,Y,03-May-1990
209867,N,03-Jul-1991

Thax for your help
 
Code:
#!perl
use strict;
use warnings;

my @months = qw(undef Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my @arr;

while (<DATA>) {
    chomp;
    my ($id, $yn, $date) = split /,/;
    my ($dd, $mm, $year) = split(/\//, $date);
    my $temp = sprintf("%s,%s,%s", 
       $id, $yn, join("-", ($dd, $months[$mm], $year)));
   for (0..($yn =~ /^[yY]$/)) {
       push(@arr, $temp);
   }
}

for (@arr) {
    print "$_\n";
}

__DATA__
200069,Y,03/05/1990
209867,N,03/07/1991

[b]Output:[/b]
200069,Y,03-May-1990
200069,Y,03-May-1990
209867,N,03-Jul-1991

naq2's code in his last post almost worked.
If you put a \n in the sprintf specification, it does
exactly what you asked for.

sprintf("%s,%s,%s,Y\n"

The only problem was that the "original" records had newlines on the end; the newly generated records didn't.


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top