Perl to move files by specific size

A

amar_auluck

Hi,

I am new to perl and want to create a script which would move all the
files from folder_1 to folder_2 with size 4,104KB in size.
Folder_1 gets updated with new files of the same size of 4,104KB and at
times a file comes in with a less size 3,100KB then 4,104KB in size.
When this happens I would like to stop the move of the files until I
receive a new good file of 4,104KB in size. And once the good file size
4,104KB is in the folder_1 the script should move the 3,100KB size
file along with the 4,104KB size file.

If any one have any suggestions please help me out.

Thanks.
 
A

A. Sinan Unur

(e-mail address removed) wrote in @g49g2000cwa.googlegroups.com:
I am new to perl and want to create a script which would move all the
files from folder_1 to folder_2 with size 4,104KB in size.
Folder_1 gets updated with new files of the same size of 4,104KB and at
times a file comes in with a less size 3,100KB then 4,104KB in size.
When this happens I would like to stop the move of the files until I
receive a new good file of 4,104KB in size. And once the good file size
4,104KB is in the folder_1 the script should move the 3,100KB size
file along with the 4,104KB size file.

What have you tried?

perldoc -f stat

Please read the posting guidelines.

Sinan
 
S

Sherm Pendley

I am new to perl and want to create a script which would move all the
files from folder_1 to folder_2 with size 4,104KB in size.

Here's a few hints to help get you started.

Use the File::Find module to "walk" down a directory tree and visit each
file. Use the -s file test operator to get a file's size.

See:
perldoc -f -X
perldoc File::Find

Or, if you're not interested in drilling down into subdirectories, you
could use opendir(), readdir(), and closedir():

perldoc -f opendir
perldoc -f readdir
perldoc -f closedir

The File::Copy module is useful for copying or moving files around.

perldoc File::Copy

Give it a try first. If you run into trouble come back and post the code
you've tried, and explain what you expected it to do and what it's doing
instead.

Oh, and if you haven't done so already, please read the posting guide-
lines for this group.

sherm--
 
A

amar_auluck

Well, I have created scripts to move file by dates but not by size and
this one is a bit triky. I can create script to move all the files but
the script I am looking for is to stop moving if there is a file found
which is less then 4,104KB in size.

Here is the script which moves index file by date and I need similar
script which woul move all the files and stop moving when a file
arrives in the folder_1 folder with a size less then 4_104KB

use strict ;
use POSIX ;
use File::Copy ;
use File::Basename ;

chdir "C:\\folder_1"
or die "Can't chdir to C:\\folder_1 $!\n" ;

for my $file (<active.VsIdx>)
{ my $datestamp = strftime("%Y.%m.%d.",localtime) ;
my ($name,$path,$suffix) = fileparse($file,"\active.VsIdx") ;

move $file,"C:\\folder_1\\$datestamp$name$suffix"
or warn "Cannot copy $file $!\n" ;
}
 
A

A. Sinan Unur

(e-mail address removed) wrote in @g49g2000cwa.googlegroups.com:

[ please quote an appropriate amount of context ]
Well, I have created scripts to move file by dates but not by size and
this one is a bit triky. I can create script to move all the files but
the script I am looking for is to stop moving if there is a file found
which is less then 4,104KB in size.

Well, you have received a couple of responses. Why don't you try reading
them, and trying to write something instead of trying to get others to
write it for you?
Here is the script which moves index file by date and I need similar
script which woul move all the files and stop moving when a file
arrives in the folder_1 folder with a size less then 4_104KB

use strict ;

use warnings;
use POSIX ;
use File::Copy ;
use File::Basename ;

chdir "C:\\folder_1"
or die "Can't chdir to C:\\folder_1 $!\n" ;

my $src = $ARGV[0] || 'c:/folder_1';
chdir $src or die "Can't chdir to $src: $!";

opendir my $src_dir, '.' or die "Cannot open dir: $src: $!";
for my $file (<active.VsIdx>)

I don't get this. How can there be more than one file returned by this
glob pattern?

Also, you probably want scalar context here:

while(my $file = <some.pattern>) {

}

Are you sure you want csh semantics?

I tend to use readdir rather than globs. But that's probably because I
am too lazy to read the docs.

use strict ;
use warnings;

my $src = shift() || 'c:/folder_1';
my $dest = shift() || 'c:/folder_2';

chdir $src or die "Can't chdir to $src: $!";
opendir my $src_dir, '.' or die "Cannot open dir: $src: $!";

while(my $file = readdir $src_dir) {
next unless /\.jpg$/;
# check the size
# move it wherever you want
}
__END__
 
A

Anno Siegel

Well, I have created scripts to move file by dates but not by size and
this one is a bit triky. I can create script to move all the files but
the script I am looking for is to stop moving if there is a file found
which is less then 4,104KB in size.

Here is the script which moves index file by date and I need similar
script which woul move all the files and stop moving when a file
arrives in the folder_1 folder with a size less then 4_104KB

There is a problem with that specification. If files are written
directly in the directory you are watching, *every* file will start out
at less than 4_104KB. Your program will "stop moving" each time a new
file is created. You will need a way of telling when a file is complete
before you check its size.

Anno
 
T

The Guru

I have writed the script but having difficulties in stoping the move if
the file size is less then 4104 mb in size

my $Filename = "/.log";

# Get file details
if(-f $Filename)
{
my @Stats = stat($Filename);
my $FileSize = $Stats[7];

# Check if file is less then 4104 MB
if($FileSize = 4104000000)
{
move $Filename, "c:\Folder_2\" ;

} elsif($FileSize < 4104000000)

}
 
E

ekkehard.horner

The said:
I have writed the script but having difficulties in stoping the move if
the file size is less then 4104 mb in size

my $Filename = "/.log";

# Get file details
if(-f $Filename)
{
my @Stats = stat($Filename);
my $FileSize = $Stats[7];

# Check if file is less then 4104 MB
if($FileSize = 4104000000)

if($FileSize == 4104000000)
 
T

The Guru

I wrote the below script which will move the test.log file if it's
equal to
4202496. But the directory the script is watching contains multipule
type of file names and this script only moves the file for one file.
How can I make it check by the extension .log and not by the file name.
Thank you.

#!/usr/bin/perl -w # force taint checks, and print warnings
use strict; # install all three strictures
$|++; # force auto flush of output buffer

use strict ;
use POSIX ;
use File::Copy ;
use File::Basename ;
use File::stat;


my $Filename = "test.log";

if(-f $Filename)
{
my $sb = stat($Filename);
my $FileSize = $sb->size;
print $FileSize ;

# Check if file is less then 4104 MB
if($FileSize == 4202496)
{
##printf("\nFilename : %s File Size %s\n", $Filename, $FileSize);
move $Filename,"c:\\Folder_2\\";
}
}

ekkehard.horner said:
The said:
I have writed the script but having difficulties in stoping the move if
the file size is less then 4104 mb in size

my $Filename = "/.log";

# Get file details
if(-f $Filename)
{
my @Stats = stat($Filename);
my $FileSize = $Stats[7];

# Check if file is less then 4104 MB
if($FileSize = 4104000000)

if($FileSize == 4104000000)
{
move $Filename, "c:\Folder_2\" ;

} elsif($FileSize < 4104000000)

}
 
J

Jeff

The said:
I wrote the below script which will move the test.log file if it's
equal to
4202496. But the directory the script is watching contains multipule
type of file names and this script only moves the file for one file.
How can I make it check by the extension .log and not by the file name.

Language barrier maybe...I don't understand exactly what you mean here.
Thank you.

#!/usr/bin/perl -w # force taint checks, and print warnings

No, -T forces taint checks
use strict; # install all three strictures
$|++; # force auto flush of output buffer

use strict ;

Again? You're *very* strict :)
use POSIX ;

Why? I don't see you using anything from there.
use File::Copy ;
use File::Basename ;

Again, I don't see any of these functions being used
use File::stat;


my $Filename = "test.log";

if(-f $Filename)
{
my $sb = stat($Filename);
my $FileSize = $sb->size;
print $FileSize ;

# Check if file is less then 4104 MB
if($FileSize == 4202496)
{
##printf("\nFilename : %s File Size %s\n", $Filename, $FileSize);
move $Filename,"c:\\Folder_2\\";
}
}

ekkehard.horner said:
The said:
I have writed the script but having difficulties in stoping the move if
the file size is less then 4104 mb in size

my $Filename = "/.log";

# Get file details
if(-f $Filename)
{
my @Stats = stat($Filename);
my $FileSize = $Stats[7];

# Check if file is less then 4104 MB
if($FileSize = 4104000000)

if($FileSize == 4104000000)

{
move $Filename, "c:\Folder_2\" ;

} elsif($FileSize < 4104000000)

}

Anno Siegel wrote:




Well, I have created scripts to move file by dates but not by size and
this one is a bit triky. I can create script to move all the files but
the script I am looking for is to stop moving if there is a file found
which is less then 4,104KB in size.

Here is the script which moves index file by date and I need similar
script which woul move all the files and stop moving when a file
arrives in the folder_1 folder with a size less then 4_104KB

There is a problem with that specification. If files are written
directly in the directory you are watching, *every* file will start out
at less than 4_104KB. Your program will "stop moving" each time a new
file is created. You will need a way of telling when a file is complete
before you check its size.

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
T

The Guru

But where can I add the File handel module in my script?


Jim said:
The said:
I wrote the below script which will move the test.log file if it's
equal to
4202496. But the directory the script is watching contains multipule
type of file names and this script only moves the file for one file.
How can I make it check by the extension .log and not by the file name.
Thank you.

Use the File::Find module and a regular expression test on the file
name (untested):

use File::Find;
find( \&moveit, '.' );
sub moveit
{
if( /\.log$/ && -s == 4202496 ) {
move $_, 'c:\Folder_2\';
}
}
 
D

Dave Weaver

The Guru said:
# Check if file is less then 4104 MB
if($FileSize == 4202496)

Either the code or comment is incorrect, which is a cruel, cruel way to
treat readers of your source code! Remember, that reader is most
likely to be *you* in the future.

move $Filename,"c:\\Folder_2\\";

Always check the return values of operations like this. You might also
find it easier on the eyes to use forward slashes instead of
backslashes:

move $Filename,"c:/Folder_2/" or die "Can't move '$Filename' : $!"
 
T

The Guru

Ran the program and it prints the processing files and nothing after
that. The program does not reach the second print statement and does
not move. There are no errors given.

But if i modify the "-s == 4202496" to "-s < 4202496" I get the
following error message:

Warning: Use of "-s" without parens is ambiguous at C:\logmove.pl line
12.
Unterminated <> operator at C:\Amar\Project\logmove.pl line 12.

Jim said:
Top-posting fixed. Please do not top-post. Please do start complying
with the guidelines for this group.
But where can I add the File handel module in my script?

What 'File handel' module? Here is a complete program you should be
able to use, although it is still untested and may contain bugs:

#!/usr/local/bin/perl
use strict;
use warnings;
use File::Copy;
use File::Find;
my $orig = 'C:/Folder_1';
my $dest = 'C:/Folder_2';
find( \&moveit, $orig );
sub moveit
{
print "processing file $orig/$_\n";
if( /\.log$/ && -s == 4202496 ) {
print "moving file $_ to $dest\n";
move $_, $dest;
}
}
__END__

That's it. That is all you need (plus two unnecessary but helpful print
messages). The program above compiles, but I cannot test it because I
do not have any 4202496-byte log files and I do not have a C: drive on
my system. If the above doesn't work for you, post your code and any
error messages you receive.

Note that the find() subroutine will descend into subdirectories if
there are any. If you do not want this behavior, then you will have to
test to see if the current directory is equal to $orig, e.g:

return unless $File::Find::dir eq $orig;

before moving the file. See 'perldoc File::Find' for details.
 
E

Eric Schwartz

Dave Weaver said:
Either the code or comment is incorrect, which is a cruel, cruel way to
treat readers of your source code! Remember, that reader is most
likely to be *you* in the future.

As a matter of personal policy, I always write numbers like that as:

4104 * 1024 * 1024

or if I'm feeling particularly sassy:

4104 * $MEGABYTE

where $MEGABYTE is defined as:

my $KILOBYTE = 1024
my $MEGABYTE = $KILOBYTE * $KILOBYTE;

Personally I don't use constant much, because it defines the constants
as functions, and I'd rather be able to interpolate them into strings
normally. But that's a personal preference.

-=Eric
 
P

Paul Lalli

Eric said:
Personally I don't use constant much, because it defines the constants
as functions, and I'd rather be able to interpolate them into strings
normally. But that's a personal preference.

use Readonly;

Readonly my $KILOBYTE => 1024;
Readonly my $MEGABYTE => 1024 * $KILOBYTE;

print "Kilo: $KILOBYTE, Mega: $MEGABYTE\n";

Paul Lalli
 
T

The Guru

This is what you have in mind?

#!/usr/local/bin/perl -w
use strict;
use warnings;
use File::Copy;
use File::Find;

use Readonly;

Readonly my $KILOBYTE => 1024;
Readonly my $MEGABYTE => 1024 * $KILOBYTE;

my $orig = 'C:/Roll';
my $dest = 'C:/RollMove';
find( \&moveit, $orig );
sub moveit
{


print "processing file $orig/$_\n";
if( /\.log$/ && -s == $MEGABYTE ) {
print "moving file $_ to $dest\n";
move $_, $dest;
}
}

Thanks.
 
B

Brian McCauley

The Guru rudely spits TOFU in out faces:

Do you have any idea how rude it is to come into a new social enviroment
and ignore requests to conduct yourself according to the local customs
of polite behaviour? Are you this rude in real life?
But if i modify the "-s == 4202496" to "-s < 4202496" I get the
following error message:

Warning: Use of "-s" without parens is ambiguous at C:\logmove.pl line
12.

This tells you the perl was not sure how to parse your code.
Unterminated <> operator at C:\Amar\Project\logmove.pl line 12.

And this tells you that it guessed wrong, it saw the '<' as the start of
a <> operator.

I suggest inserting a pair of parentheses to make it unambiguous that
the '<' is a less-than operator.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top