Home: Perl Programming Help: Beginner:
Processing compressed files



seanliam
Novice

Dec 17, 2010, 5:29 AM


Views: 4557
Processing compressed files

Hi,

I am using File::Find to search through a directory structure and when I find a file I am running zgrep (all the files are compressed) to search for a string within each file.

My current code looks something like this:

Code
#!/usr/bin/perl 

use File::Find;

$directory = $ARGV[0];

find(\&wanted, $directory);

sub wanted {
if (-f $_) {
system("zgrep -l -m 1 -i 'string' $_");
}
}


As expected this returns the file name of any matching files. What I would like ideally is to then copy any matching files to another directory but, am a little stuck as to how to do this.

Any pointers would be greatly appreciated.

Cheers

Sean


FishMonger
Veteran / Moderator

Dec 17, 2010, 6:07 AM


Views: 4555
Re: [seanliam] Processing compressed files

See: File::Copy
http://search.cpan.org/~jesse/perl-5.12.2/lib/File/Copy.pm


seanliam
Novice

Dec 17, 2010, 6:11 AM


Views: 4552
Re: [FishMonger] Processing compressed files

Thanks

My question really is how do i pass the output to File::Copy rather than just print it?

Cheers

Sean


rovf
Veteran

Dec 17, 2010, 8:03 AM


Views: 4549
Re: [seanliam] Processing compressed files

Use qx() instead of system():




Code
my $output_of_command=qx(zgrep ...); 
if($? == 0) {
copy(....)
} else {
# Error handling
}



rovf
Veteran

Dec 17, 2010, 8:06 AM


Views: 4548
Re: [seanliam] Processing compressed files

Addendum:

Of course you first need to process the output.

If your command returns several lines, one file per line, you will have an easier life by running it in list context:

my @output_from_command=qx(...)

Don't forget to chomp your output, if necessary!

Ronald


seanliam
Novice

Dec 17, 2010, 9:34 AM


Views: 4543
Re: [rovf] Processing compressed files

Excellent! That looks like it might just work :)

Now I just need to work out how to process these directories with spaces in the name?!?!


rovf
Veteran

Dec 17, 2010, 11:32 AM


Views: 4540
Re: [seanliam] Processing compressed files

Spaces in directory- and filenames are evil. One must be a very rotten soul to punish the world by creating a filename containing a space...

Best is to avoid shelling out from your program (and hence circumvent quoting issues).

Ronald


FishMonger
Veteran / Moderator

Dec 17, 2010, 5:23 PM


Views: 4527
Re: [rovf] Processing compressed files


In Reply To
Spaces in directory- and filenames are evil. One must be a very rotten soul to punish the world by creating a filename containing a space...

Ronald

I think we need to "thank" Microsoft for promoting that evil.


rovf
Veteran

Dec 18, 2010, 6:52 AM


Views: 4517
Re: [FishMonger] Processing compressed files

I know, I just didn't want to say it explicitly ;-)


seanliam
Novice

Dec 19, 2010, 12:06 PM


Views: 4503
Re: [rovf] Processing compressed files

evil indeed!!

Really struggling with them at the moment. File::Find is doing the job of traversing the directory structure nicely but when I try to use File::Copy to copy any matching files I get a no such file or directory error!


FishMonger
Veteran / Moderator

Dec 19, 2010, 1:23 PM


Views: 4501
Re: [seanliam] Processing compressed files

We can't help in pointing out what's wrong without seeing the code.


rovf
Veteran

Dec 20, 2010, 1:54 AM


Views: 4496
Re: [seanliam] Processing compressed files

One annoying thing with File::Copy is that you never know whether the error message applies to the source or to the destination, so I suggest that before doing the copy, you check source and destination for existence.


seanliam
Novice

Dec 20, 2010, 8:16 AM


Views: 4492
Re: [FishMonger] Processing compressed files

Code is below


Code
#!/usr/local/bin/perl -w 

use File::Find;
use File::Copy;

$directory = $ARGV[0];

find(\&wanted, $directory);


sub wanted {
if (-f $_) {
qx("zgrep -H -l -m 1 -i 'string' $_");
if ($? == 0) {
copy("$File::Find::name", "/file/path/$_") or die "Copy failed: $!";
}
}
}



FishMonger
Veteran / Moderator

Dec 20, 2010, 8:48 AM


Views: 4490
Re: [seanliam] Processing compressed files

I see a number of issues.

1) It's better to use the warnings pragma instead of the -w switch.

2) You're missing the strict pragma.

3) You're making the assumption that a valid directory is being passed.

4) You're not verifying the existence of that directory

5) You should not be quoting stand alone vars.

6) You're not including the filename in the die statement.

Try this version.

Code
#!/usr/local/bin/perl 

use warnings;
use strict;
use File::Find;
use File::Copy;

@ARGV or die "useage: $0 [directory]\n";

my $directory = $ARGV[0];
-d $directory or die "$directory does not exist\n";

my $dest_path = '/file/path';
-d $dest_path or die "$dest_path does not exist\n";

find(\&wanted, $directory);


sub wanted {
-f or return;

qx("zgrep -H -l -m 1 -i 'string' $_");

if ($? == 0) {
copy($File::Find::name, "$dest_path/$_")
or die "Failed to copy '$File::Find::name' to '$dest_path/$_' <$!>";
}
}



rovf
Veteran

Dec 21, 2010, 2:00 AM


Views: 4478
Re: [seanliam] Processing compressed files

Your usage of qx() doesn't make sense. You collect the output of zgrep, and then throw it away. From your original posting, I had concluded that you need the stdout of zgrep; but if you don't need it, you can as well use system().

Also, the code doesn't incorporate the suggestions I gave you in my last reply....

Ronald