I want to download files with .gz extension using Perl. I have wrote the following code:
#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
my $url = 'http://www.ebi.ac.uk/thornton-srv/databases/pdbsum/2kri/igrow.out.gz';
my $file = 'prot-prot.txt';
getstore($url, $file);
But I have realized that this code only works with text files and not compressed files. Any idea how I should change this code in order to download .gz files?
Thanks;
#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
my $url = 'http://www.ebi.ac.uk/thornton-srv/databases/pdbsum/2kri/igrow.out.gz';
my $file = 'igrow.out.gz';
getstore($url, $file);
If you want the perl script to unzip the file, you can either uses system() to run gunzip or search CPAN for a suitable perl module.
if you don't like typing 'igrow.out.gz twice (with the possibility of forgetting to change one of the filenames) replace $file = ... with something like
(my $file = $url) =~ s!^.*/!!;
Use File::Fetch.
Related
I'm writing a Perl scipt that unzips the zip file and moves the content of zip file to a directory, however I want to skip the zip file which do not have any content in it. How can I filter these files. For unzipping the file I'm using
unzip_content = system("unzip -d <directory> -j -a <filepath>")
Could anyone suggest me anyway to check if it does not contain anything.
I tried with checking the filesize using -s $filename but later I got some files with filesize 22 byte but with no content in it.
You can use Archive::Zip to achieve all of that inside of your Perl program without shelling out. You need to check if the archive contains anything, which can be done with the numberOfMembers method.
use strict;
use warnings;
use Archive::Zip qw/:ERROR_CODES/;
my #files = ...;
foreach my $file (#files) {
my $zip = Archive::Zip->new;
# skip if archive cannot be opened
next unless $zip->read($file) == AZ_OK;
# skip if archive is empty
next unless $zip->numberOfMembers;
# extract everything
$zip->extractTree({zipName => '<directory>'});
}
An other way to check the same thing is to calculate the MD5 hash of the file. MD5 hash of all empty zip files would be 76cdb2bad9582d23c1f6f4d868218d6c.
Helpful links:
minimum size zip file
Digest::MD5
use strict;
use warnings;
use Digest::MD5 qw(md5 md5_hex md5_base64);
my $filedir = "/home/docs/file.zip";
open FILE, "$filedir";
my $ctx = Digest::MD5->new;
$ctx->addfile (*FILE);
my $hash = $ctx->hexdigest;
close (FILE);
if($hash eq '76cdb2bad9582d23c1f6f4d868218d6c')
{
# empty file
}
I will add some extra file while I make .exe file using perl (PP). Please see my below code for making .exe file.
pp -gui -a 7z.exe -a 7z.dll -o gui_curl.exe gui_curl.pl
Both file are added when .exe build, But it does not work. I don't know why?
I used both file in my code, like below:-
system("7z.exe a $current_dir/$file_name.tar $current_dir");
system("7z.exe a $current_dir/$file_name.gz $current_dir/$file_name.tar");
Please suggest me how to use this file. I don't want to put this file outside from exe
This is my suggested solution. It does not use 7zip which I have no idea how to make work within pp.
It's based on Archive::Tar instead.
#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
use Archive::Tar;
my $current_dir = getcwd();
my $file_name = 'archive';
my #files_to_archive;
opendir(DIR, $current_dir) or die $!;
while (my $file = readdir(DIR)) {
next if ($file =~ m/^\./);
push #files_to_archive, $file;
}
closedir(DIR);
my $tar = Archive::Tar->new;
$tar->add_files(#files_to_archive);
$tar->write("$current_dir/$file_name.tgz", COMPRESS_GZIP);
my $extract_dir = '/tmp/test_arc';
mkdir $extract_dir unless (-d $extract_dir );
chdir $extract_dir;
$tar->extract('archive.tar');
Afterwards, you run
pp -o zipper.exe archive.pl -M Archive::Tar
and you should have your standalone archiver.
Is it possible to use Perl's move function from File::Copy or any other perl module to replace
system("mv -f /../directory1/* /../directory2/");
OR
replace a code like,
#!/usr/bin/perl -w
use strict;
use warnings;
use File::Copy;
my $dir1= "/..path../directory1";
my $dir2="/..path../directory2";
opendir DH, $dir1;
while(my $file = readdir DH) {
move "$dir1/$file" , "$dir2/$file";
}
closedir DH;
What i want to do is move all the contents from directory1 to directory2 using some Perl module, instead of writing a code for it.
Exploring the possibility of using a simple perl line, may be like,
move ("directory1/*","directory2/" ) ; using some perl module.
I have a perl script and its been executing from "/root/pkt/sw/se/tool" path and would need the complete directory path inside the script.
Can you please let me know how would i get the complete path?
sample.pl
our ($tool_dir);
use strict;
use warnings;
BEGIN {
$tool_dir = $0;
my $home_path = $tool_dir
$home_path =~ s|\w*/\w*/\w*$||;
my $target_path ="obj/Linux-i686/usr/share/ddlc/lib";
$lib_dir = "$home_path$target_path";
unshift(#INC, $lib_dir);
}
And i am executing this script from "pkt/sw/se/tool" path but here i am getting only "pkt/sw/se/tool" instead of "/root/pkt/sw/se/tool"
my perl script is available under /root/pkt/sw/se/tools/sample.pl
You can use the CWD module (http://perldoc.perl.org/Cwd.html) (code take from that page)
use Cwd;
my $dir = getcwd;
use Cwd 'abs_path';
my $abs_path = abs_path($file);
or you could execute the pwd command
$cwd = `pwd`;
If you just want the directory, not the full path, you could check out an existing answer at Print current directory using Perl
Use one of the modules already mentioned, never use backticks - unless you fully understand the risks and implications of doing so. If you do want to run 'pwd' then call it via something like IPC::Run3.
Examples:
#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
use IPC::Run3;
# CWD
my $working_dir_cwd = getcwd;
print "Woring Dir (Cwd): $working_dir_cwd\n";
# IPC::Run3
my ($in, $out, $err);
my #command = qw/pwd/;
run3 \#command, $in, \$out, \$err or die $?;
print "Working Dir (pwd): $out\n";
You can use FindBin to locate directory of original perl script.
use FindBin;
use lib "$FindBin::Bin/../../../obj/Linux-i686/usr/share/ddlc/lib";
I tried to run a simple copy of one file to another folder using Perl
system("copy template.html tmp/$id/index.html");
but I got the error error: The syntax of the command is incorrect.
When I change it to
system("copy template.html tmp\\$id\\index.html");
The system copies another file to the tmp\$id foler
Can someone help me?
I suggest you use File::Copy, which comes with your Perl distribution.
use strict; use warnings;
use File::Copy;
print copy('template.html', "tmp/$id/index.html");
You do not need to worry about the slashes or backslashes on Windows because the module will take care of that for you.
Note that you have to set relative paths from your current working directory, so both template.html as well as the dir tmp/$id/ needs to be there. If you want to create the folders on the fly, take a look at File::Path.
Update: Reply to comment below.
You can use this program to create your folders and copy the files with in-place substitution of the IDs.
use strict; use warnings;
use File::Path qw(make_path);
my $id = 1; # edit ID here
# Create output folder
make_path("tmp/$id");
# Open the template for reading and the new file for writing
open $fh_in, '<', 'template.html' or die $!;
open $fh_out, '>', "tmp\\$id\index.html" or die $!;
# Read the template
while (<$fh_in>) {
s/ID/$id/g; # replace all instances of ID with $id
print $fh_out $_; # print to new file
}
# Close both files
close $fh_out;
close $fh_in;