recursively file delete from directory in perl - perl

I am new in perl script. I want to write perl which delete previous backup file and extract new backup file from dropbox and rename with specific file name.
Example:
backup location:
D:\Database\store_name\ containing .bak files
Actual folder data
D:\Database\Mahavir Dhanya Bhandar\ contain .bak file
D:\Database\Patel General Store\ containg .bak files
..so on
How can write perl script code which delete *.bak files store_recursively
2.extract new backup file from dropbox and rename with specific file name.

Have you looked into walking your file tree. http://rosettacode.org/wiki/Walk_a_directory/Recursively. Combine this with simple file operations (copying, deleting, etc.) and you should be good.
use File::Find qw(find);
my $dir = "D:\Database\Store_Name";
find sub {unlink $File::Find::name if /\.bak$/}, $dir;
and assuming that connectToDropbox() connects to your dropbox
use File::Copy;
use File::Find qw(find);
my $backup = connectToDropbox();
my $dir = "D\Database\Store_Name";
find sub {copy($backup -> getFile("file"), "newFile")} $dir;
of course, this assumes that you already can set up a connection and such to Dropbox. If not, there is a good CPAN libraryhere you can check out.

Related

FTP upload directory and subdirectories in Perl

I am trying to FTP a directory that has subdirectories with files and images using Perl.
I tried using $ftp->rput() under Net::FTP::Recursive. But this uploads all files under local current working directory.
Is there a way to give the path of local directory and all folders and files are uploaded. Please guide.
You need to change your own working directory temporarily.
rput ( [FlattenTree => 1] [,RemoveLocalFiles => 1] )
The recursive put
method call. This will recursively send the local current working
directory and its contents to the ftp object's current working
directory.
Perl's builtin chdir can be used to change the directory. Use the Cwd module to get the current one if you need to go back.
use strict;
use warnings;
use Cwd;
use Net::FTP::Recursive;
# ...
# get the current directory
my $old_current_dir = getcwd();
# change directory to the one you want to upload
chdir('path/to/updloaddir');
# upload
$ftp->rput();
# change back
chdir($old_current_dir);

Trying to pass a subdirectory as a parameter in Perl

I have a Perl program to read .html's and only works if the program is in the same directory as the .html's.
I would like to be able to start in different directories and pass the html's location as a parameter. The program (shell example below) traverses the subdirectory "sub"
and its subdirectories to look for .html's, but only works when my perl file is in the same subdirectory "sub". If I put the Perl file
in the home directory, which is one step back from the subdirectory "sub", it doesn't work.
In the shell, if I type "perl project.pl ./sub" from my home directory, it says could
not open ./sub/file1.html. No such file or directory. Yet the file does exist in that exact spot.
file1.html is the first file it is trying to read.
If I change directories in the shell to that subdirectory and move the .pl file
there and then say in the shell: "perl project.pl ./" everything is ok.
To search the directories, I have been using the File::Find concept which I found here:
How to traverse all the files in a directory; if it has subdirectories, I want to traverse files in subdirectories too
Find::File to search a directory of a list of files
#!/usr/bin/perl -w
use strict;
use warnings;
use File::Find;
find( \&directories, $ARGV[0]);
sub directories {
$_ = $File::Find::name;
if(/.*\.html$/){#only read file on local drive if it is an .html
my $file = $_;
open my $info, $file or die "Could not open $file: $!";
while(my $line = <$info>) {
#perform operations on file
}
close $info;
}
return;
}
In the documentation of File::Find it says:
You are chdir()'d to $File::Find::dir when the function is called,
unless no_chdir was specified. Note that when changing to directories
is in effect the root directory (/) is a somewhat special case
inasmuch as the concatenation of $File::Find::dir, '/' and $_ is not
literally equal to $File::Find::name.
So you actually are at ~/sub already. Only use the filename, which is $_. You do not need to overwrite it. Remove the line:
$_ = $File::Find::name;
find changes directory automatically so that $File::Find::name is no longer relative to the current directory.
You can delete this line to get it to work:
$_ = $File::Find::name;
See also File::Find no_chdir.
From the File::Find documentation:
For each file or directory found, it calls the &wanted subroutine.
(See below for details on how to use the &wanted function).
Additionally, for each directory found, it will chdir() into that
directory and continue the search, invoking the &wanted function on
each file or subdirectory in the directory.
(emphasis mine)
The reason it's not finding ./sub/file1.html is because, when open is called, File::Find has already chdired you into ./sub/. You should be able to open the file as just file1.html.

Perl Rar a whole folder

I want to rar a whole folder with Perl and Archive::Rar. For example the folder /root/pictures.
I have found only a way to rar single files.
I tried to find all files in the folder and rar them, but then I always have the whole path sticking to them (/root/pictures) in the rar archive.
I want only the /pictures folder plus its contents. Is that possible?
The folder structure of the files stored in the archive will be the same as the file names that you pass to the Add method. (Although you can add them without any containing folder at all using the -excludepaths option.)
If you chdir to the \root directory before adding the files to the archive, and specify all your files as pictures\file1.jpg etc. then the result should be as you want.
Something like this
use strict;
use warnings;
use Archive::Rar;
use autodie;
chdir '\root';
my $rar = Archive::Rar->new(-archive => 'pictures.rar');
$rar->Add(-files => [ glob 'pictures\*' ]);
Clearly you could add a path to the rar file name if you want the archive stored elsewhere.
At first you have to get a list of files from defined directory:
use File::Find;
my #content;
find( \&wanted, '/some/path');
sub wanted {
push #content, $File::Find::name;
return;
}
After that you may use the Archive::Rar to pack it.
use Archive::Rar;
my $rar = Archive::Rar->new();
$rar->Add(
-size => $size_of_parts,
-archive => $archive_filename,
-files => \#content,
);

Redirect unzip output to particular directory using Perl

I want to uncompress zipped file say, files.zip, to a directory that is different from my working directory.
Say, my working directory is /home/user/address and I want to unzip files in /home/user/name.
I am trying to do it as follows
#!/usr/bin/perl
use strict;
use warnings;
my $files= "/home/user/name/files.zip"; #location of zip file
my $wd = "/home/user/address" #working directory
my $newdir= "/home/user/name"; #directory where files need to be extracted
my $dir = `cd $newdir`;
my #result = `unzip $files`;
But when run the above from my working directory, all the files get unzipped in working directory. How do I redirect the uncompressed files to $newdir?
unzip $files -d $newdir
Use Perl command
chdir $newdir;
and not the backticks
`cd $newdir`
which will just start a new shell, change the directory in that shell, and then exit.
Though for this example, the -d option to unzip is probably the simplest way to do what you want (as mentioned by ennuikiller), for other types of directory-changing, I like the File::chdir module, which allows you to localize directory changes, when combined with the perl "local" operator:
#!/usr/bin/perl
use strict;
use warnings;
use File::chdir;
my $files= "/home/user/name/files.zip"; #location of zip file
my $wd = "/home/user/address" #working directory
my $newdir= "/home/user/name"; #directory where files need to be extracted
# doesn't work, since cd is inside a subshell: my $dir = `cd $newdir`;
{
local $CWD = $newdir;
# Within this block, the current working directory is $newdir
my #result = `unzip $files`;
}
# here the current working directory is back to what it was before
You can also use the Archive::Zip module. Look specifically at the extractToFileNamed:
"extractToFileNamed( $fileName )
Extract me to a file with the given name. The file will be created with default modes. Directories will be created as needed. The $fileName argument should be a valid file name on your file system. Returns AZ_OK on success. "

How can I copy all files with a given extension?

I need to copy all *.exe files in some directory to other virtual drive .
If I was writing batch script I would do xcopy "%mycopyposition%\*.exe".
But I think it will be a bad idea in Perl script .
I seen a File::Copy module, but couldn't see how to do that.
Try this:
use File::Copy;
for my $file (<*.exe>) {
# Copies from directory $mycopyposition to current directory.
copy "$mycopyposition/$file", $file or die "copy $file failed: $!";
}
I think it is an excellent idea to use xcopy. It does what you want. Plus, it preserves time stamps and other attributes. Has some very useful options.