Hi,

I wud like some help in assembling the kit.

Thanks in Advance

--- Rob Dixon <[EMAIL PROTECTED]> wrote:
> Mohit_jain01 wrote:
> >
> > > From: Rob Dixon
> > >
> > > Mohit_jain01 wrote:
> > > >
> > > > I am facing a problem with text file manipulation with Perl.
> > > >
> > > > I have a file with over 2 lac lines of data.
> > > > I need to find the duplicates(strings) in the file and copy those records into 
> > > > another
> file.
> > > >
> > > > Is there a function/module  in Perl by which I can read the duplicates in a 
> > > > file at one go
> and print them
> > > > on to another file.
> > >
> > > Before we can help you we need to know a little more of your problem.
> > >
> > > Are you looking for duplicate lines in the file, or duplicate strings defined
> > > in some other way? How big is the file you want to read (how many lines
> > > or strings do you want to compare)?
> > >
> > > There are modules which will help you write your program, but exactly
> > > how you go about it depends on the details of your problem.
> >
> > I have a big file containing about 200000 lines. This file basically contains some 
> > records. A
> sample of the file is as given
> > below:
> >
> > dn: cn=1148734,ou=Employees,dc=jci,dc=com
> >
> > displayname: Herek, Moriah L
> >
> > jdirlastfourssn: 2888
> >
> > dn: cn=1148735,ou=Employees,dc=jci,dc=com
> >
> > displayname: Pelletier, Michael J
> >
> > jdirlastfourssn: 8719
> >
> > uid: cpellem
> >
> [snip data]
> >
> > What I need to do is:
> >
> > 1. Take the first entry and get the value of the display name and jdirlastfourssn 
> > attribute.
> >
> > 2. Check whether there is another record with the same display name attribute 
> > value.
> >        (There cud be multiple records)
> >
> >  3. If so then extract both record and write them into another file.
> >
> >  4. Delete these duplicate records from the parent file.
> >
> > 5. Do that for all records.
> >
> 
> I'm not clear whether you mean 200K lines or 200K records (which seem to be mostly
> 6 lines each except for 'Pelletier, Michael J' which has an additional pair of
> lines for a 'uid' value. But, even if it were 200K records at about 100 characters
> each this would be 20Mb, which is well within the capacity of all but the smallest
> computers these days. This problem is far easier with all the data in memory, so
> I'll go that way, and if you find it's not working or is too slow we'll think again.
> 
> OK, so let me rewrite your algorithm a little.
> 
> - Read all records into memory
> - While there are records left
> -   calculate a 'key' from the display name and serial number
> -   find all records in the data with a matching key
> -   if there was only one then print it to parent file, else print them to file 2
> -   delete them from the list
> 
> From the top:
> 
> 
> "Read in all of the records"
> 
> It looks like all the information starts with a line beginning with 'dn:'. If this
> is wrong we'll have to change it.
> 
>   my @records;
> 
>   while (<DATA>) {
>     push @records, '' if /^dn:\s+/;
>     $records[-1] .= $_;
>   }
> 
> 
> Before the loop, how about a subroutine which, given one of the multi-line records,
> will return a key value containing the name and serial number. This picks out the
> strings and concatenates them with a tab character in between, chosen because it
> is unlikely to appear in the data itself.
> 
>   sub keyval {
>     my $rec = shift;
>     my ($name, $sn);
>     ($name) = $rec =~ m/^displayname:\s+(.+)/m;
>     ($sn) = $rec =~ m/^jdirlastfourssn:\s+(\d+)/m;
>     join "\t", $name, $sn;
>   }
> 
> 
> "While there are records left" Here's the loop, including a couple of lines to
> remove all non-blank entries from the beginning which will be left by the call
> to 'delete' that you see in a moment.
> 
>   while (@records) {
>     until (exists $records[0]) {
>       shift @records;
>     }
>     :
>   }
> 
> 
> "Calculate a 'key' from the display name and serial number"
> 
>   my $key = keyval($records[0]);
> 
> "Find all records in the data with a matching key" This call to 'map'
> returns a list of indices of all the records in the array which have
> a matching key value. This is bound to include the index zero as the
> first record matches itself. If there are more then the length of the
> array will be more than 1.
> 
>   my $i = 0;
>   my @slice = map {
>     my @i = $i++;
>     defined $_ and keyval($_) eq $key ? @i : ()
>   } @records;
> 
> 
> The next two steps together: "If there was only one then print it to
> parent file, else print them to file 2. Delete them from the list"
> The 'delete' function usefully returns a list of all the records
> it deleted, so we can just print the results of deleting the array
> slice.
> 
>   if (@slice == 1) {
>     print PARENT delete @[EMAIL PROTECTED];
>   }
>   else {
>     print FILE2 delete @[EMAIL PROTECTED];
>   }
> 
> 
> And you're done. Clearly you need to open filehandles DATA for read
> and PARENT and FILE2 for write, but the program's there otherwise.
> 
> Let us know if you need help assembling the kit.
> 
> HTH,
> 
> Rob
> 
> 
> 
> 
> -- 
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 


__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to