Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Grouping files with the same name...

by A200560 (Novice)
on Nov 05, 2007 at 11:47 UTC ( [id://648994]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I have a big directory with pdf, xml and xls files. Every customer can have this kind of files and each files has the following names: customerxxx.pdf, customerxxx.xml and customerxxx.xls.

I would create automatically a zip for each customer (customerxxx.zip)containing his own files, grouping the entire set of files.

How can I achieve this?

Thanks.

Replies are listed 'Best First'.
Re: Grouping files with the same name...
by ikegami (Patriarch) on Nov 05, 2007 at 13:22 UTC
    use File::Spec::Functions qw( catfile ); sub get_files_in_dir { my ($dir_name) = @_; opendir(my $dh, $dir_name) or die("Unable to open dir \"$dir_name\": $!\n"); return map catfile($dir_name, $_), grep -f, grep !/^\.\.?\z/, readdir($dh); } my $dir_name = '...'; # Get list of files. my @files = get_files_in_dir($dir_name); # Group files by customer. my %files_by_cust; foreach (@files) { my ($cust_id) = /^customer(\d+)\./ or next; push @{ $files_by_cust{$cust_id} }, $_; } # Process each customer's files. foreach my $cust_id (keys %files_by_cust) { # List of files is in @{ $files_by_cust{$cust_id} }. # ... }

    Updated: Added omitted call to opendir.

Re: Grouping files with the same name...
by erroneousBollock (Curate) on Nov 05, 2007 at 12:15 UTC
    I would create automatically a zip for each customer (customerxxx.zip)containing his own files, grouping the entire set of files.
    So you'd iterate the customers. All the known customers? Or just the distinct customers you can discern from the filenames in the "big directory"?

    One approach (update: implemented by ikegami below) would be as follows:

    Use opendir/readdir/closedir to find all the filenames, building a hash where the keys are the the distinct customer numbers (use a regexp to retrieve it from the filename) and the values are references to lists of filenames for each customer number.

    When you've built the hash, iterate the keys (customers) where for each key you build a zip file (using say Archive::Zip) adding the files listed against that key to the archive.

    You might even remove the source files at the same time if that's your preference.

    -David

Re: Grouping files with the same name...
by siva kumar (Pilgrim) on Nov 05, 2007 at 12:33 UTC
    If you are sure that you will be receiving one ".xml" file for all the customers then
    1. Read list of unique customers.
    @xmlFileNames=grep !/^\.\.?$/ && /\.xml$/,readdir(DIR); The number of xml you get is the number of total customers.

    2. Loop through each customer and create zip.
    foreach my $customer (@xmlFileNames) { $customer =~ s/\.xml//g; system ("/usr/local/bin/unzip ${customer}.zip ${customer}.xml ${ +customer}.pdf ${customer}.xls"); }
Re: Grouping files with the same name...
by shoness (Friar) on Nov 05, 2007 at 13:31 UTC
    Not a perl answer, but it's simpler with a shell script...
    #!/bin/bash for f in customer*.xml do /usr/bin/zip ${f%xml}zip ${f} ${f%xml}pdf ${f%xml}xls; done
      thanks to everybody, very useful tips.
        ...but my platform is windows, how the grep?
Re: Grouping files with the same name...
by arcnon (Monk) on Nov 05, 2007 at 17:50 UTC
    #!/usr/bin/perl use strict; use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); my $some_dir = 'sql'; opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!"; my @files = readdir(DIR); closedir DIR; @files = sort @files; my $f2z; foreach my $file (@files){ if ($file=~/^\.$/){ next; } elsif(-d $file){ next; } else{ my ($name,$ext) = split(/\./, $file); push(@{$f2z->{$name}}, $file); } } while (my($key, $value) = each(%{$f2z})){ #print $key.", ".$value."<br />"; my $zip = Archive::Zip->new(); chdir($some_dir); foreach my $v (@{$value}){ $zip->addFile( "$v" ); } unless ( $zip->writeToFileNamed("$key.zip") == AZ_OK ) { die 'write error'; } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://648994]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-19 11:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found